Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
/*                                                                 */
/* This library is free software; you can redistribute it and/or   */
/* modify it without any restrictions. This library is distributed */
/* in the hope that it will be useful, but without any warranty.   */

/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
/* partially copyrighted (C) 1993 by Hartmut Schirmer */
/* HH: Added 4bpp support, and use bytesperpixel. */

#include <stdio.h>
#include "vga.h"
#include "libvga.h"
#include "driver.h"

static inline void read_write(unsigned long off)
{
    *(GM+off)=*(GM+off)+1;
}

int vga_drawpixel(int x, int y)
{
    unsigned long offset;
    int c;

    if (MODEX) {
             /* select plane */
             __svgalib_outseq(0x02,1 << (x & 3));
             /* write color to pixel */
             *(GM+y * CI.xbytes + (x >> 2))=COL;
        return 0;
    }
    switch (__svgalib_cur_info.bytesperpixel) {
    case 0:                     /* Must be 2 or 16 color mode. */
        /* set up video page */
        offset = y * CI.xbytes + (x >> 3);
        vga_setpage(offset >> 16);
        offset &= 0xffff;

        /* select bit */
        __svgalib_outgra(0x08, 0x80 >> (x & 7));

        /* read into latch and write dummy back */
        read_write(offset);
        break;
    case 1:
        offset = y * CI.xbytes + x;

        if (__svgalib_modeinfo_linearset & IS_LINEAR ) {
            *(LINEAR_POINTER+offset)=COL;
        } else {
            /* select segment */
            vga_setpage(offset >> 16);
   
            /* write color to pixel */
            *(GM+(offset&0xffff))=COL;
        }
        break;
    case 2:
        offset = y * CI.xbytes + x * 2;
        if (__svgalib_modeinfo_linearset & IS_LINEAR ) {
            *(uint16_t *)(LINEAR_POINTER+offset)=COL;
        } else {
            vga_setpage(offset >> 16);
            *(uint16_t *)(GM+(offset&0xffff))=COL;
        }
        break;
    case 3:
        c = COL;
        offset = y * CI.xbytes + x * 3;
        if (__svgalib_modeinfo_linearset & IS_LINEAR ) {
            /* Only on little endian */
            *(LINEAR_POINTER+offset)=COL&0xff;
            *(LINEAR_POINTER+offset+1)=(COL&0xff00)>>8;
            *(LINEAR_POINTER+offset+2)=(COL&0xff0000)>>16;
        } else {
            vga_setpage(offset >> 16);
            switch (offset & 0xffff) {
            case 0xfffe:
                *(GM+0xfffe)=COL&0xff;
                *(GM+0xffff)=(COL&0xff00)>>8;
                vga_setpage((offset >> 16) + 1);
                *(GM)=(COL&0xff0000)>>16;
                break;
            case 0xffff:
                *(GM+0xffff)=COL&0xff;
                vga_setpage((offset >> 16) + 1);
                *(GM)=(COL&0xff00)>>8;
                *(GM+1)=(COL&0xff0000)>>16;
                break;
            default:
                offset &= 0xffff;
                *(GM+offset)=COL&0xff;
                *(GM+offset+1)=(COL&0xff00)>>8;
                *(GM+offset+2)=(COL&0xff0000)>>16;
                break;
            }
        }
        break;
    case 4:
        offset = y * __svgalib_cur_info.xbytes + x * 4;
        if (__svgalib_modeinfo_linearset & IS_LINEAR ) {
            *(uint32_t *)(LINEAR_POINTER+offset)=COL;
        } else {
            vga_setpage(offset >> 16);
            *(uint32_t *)(GM+(offset&0xffff))=COL;
        }
        break;
    }
    return 0;
}

int vga_getpixel(int x, int y)
{
    unsigned long offset;
    unsigned char mask;
    int pix = 0;

    if (MODEX) {
             /* select plane */
             __svgalib_outseq(0x02, 1 << (x & 3) );        
        return gr_readb(y * CI.xbytes + (x >> 2));
    }
    switch (__svgalib_cur_info.bytesperpixel) {
    case 0:                     /* Must be 2 or 16 color mode. */
             /* set up video page */
             offset = y * CI.xbytes + (x >> 3);
             vga_setpage(offset >> 16);
             offset &= 0xffff;

             /* select bit */
             mask = 0x80 >> (x & 7);
             pix = 0;
             __svgalib_outgra(0x04,0);
             if (gr_readb(offset) & mask)
                pix |= 0x01;
             __svgalib_outgra(0x04,1);
             if (gr_readb(offset) & mask)
                pix |= 0x02;
             __svgalib_outgra(0x04,2);
             if (gr_readb(offset) & mask)
                pix |= 0x04;
             __svgalib_outgra(0x04,3);
             if (gr_readb(offset) & mask)
                pix |= 0x08;
        return pix;
    case 1:
        offset = y * CI.xbytes + x;
        if (__svgalib_modeinfo_linearset & IS_LINEAR ) {
            return *(LINEAR_POINTER+offset);
        }
        /* select segment */
        vga_setpage(offset >> 16);
        return gr_readb(offset & 0xffff);
    case 2:
        offset = y * CI.xbytes + x * 2;
        if (__svgalib_modeinfo_linearset & IS_LINEAR ) {
            return *(uint16_t *)(LINEAR_POINTER+offset);
        }
        vga_setpage(offset >> 16);
        return gr_readw(offset & 0xffff);
    case 3:
        offset = y * CI.xbytes + x * 3;
        if (__svgalib_modeinfo_linearset & IS_LINEAR ) {
            return (*(LINEAR_POINTER+offset)) + (*(LINEAR_POINTER+offset+1)<<8) +
                   (*(LINEAR_POINTER+offset+2)<<16);
        }
        vga_setpage(offset >> 16);
        switch (offset & 0xffff) {
        case 0xfffe:
            pix = gr_readw(0xfffe);
            vga_setpage((offset >> 16) + 1);
            return pix + (gr_readb(0) << 16);
        case 0xffff:
            pix = gr_readb(0xffff);
            vga_setpage((offset >> 16) + 1);
            return pix + (gr_readw(0) << 8);
        default:
            offset &= 0xffff;
            return gr_readw(offset) + (gr_readb(offset + 2) << 16);
        }
        break;
    case 4:
        offset = y * __svgalib_cur_info.xbytes + x * 4;
        if (__svgalib_modeinfo_linearset & IS_LINEAR ) {
            return *(uint32_t *)(LINEAR_POINTER+offset);
        }
        vga_setpage(offset >> 16);
        return gr_readl(offset & 0xffff);
    }
    return 0;
}