/* 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 */

/* Converted to especially ugly code and seriously hacked for Mach32: */
/* M. Weller in 1994                                                  */
#include <stdlib.h>

#include "vga.h"
#include "libvga.h"
#include "driver.h"


int vga_setpalette(int index, int red, int green, int blue)
{
    if ((__svgalib_chipset == MACH32) && SVGAMODE(CM))
	{
	/* Actually the same but we are in 8514 mode and the dac
	   does not respond to the VGA circuitry anymore... */
	port_out(index, PEL8514_IW); 
	__vga_delay();
	port_out(red, PEL8514_D);
	__vga_delay();
	port_out(green, PEL8514_D);
	/* Uh yes.. and I didn't find a way to wait for hsync, so... */
	__vga_delay();
	port_out(blue, PEL8514_D);
	return 0;
	}
    /* select palette register */
    port_out(index, PEL_IW); 

    /* write RGB components */
    __vga_delay();
    port_out(red, PEL_D);
    __vga_delay();
    port_out(green, PEL_D);
    if (SCREENON) {		 /* writing the `blue' register will   */
      while (!(inb(0x3da) & 1)); /* load the dac. Waiting for vertical */
      while (inb(0x3da) & 1);    /* or horizontal retrace will load    */
    } else			 /* the dac without disturbances       */	
      __vga_delay();
    port_out(blue, PEL_D);
    return 0;
}


int vga_getpalette(int index, int *red, int *green, int *blue)
{
    if ((__svgalib_chipset == MACH32) && SVGAMODE(CM))
	{
	/* Actually the same but we are in 8514 mode and the dac
	   does not respond to the VGA circuitry anymore... */
	port_out(index, PEL8514_IR); 
    	__vga_delay();
    	*red = (int) port_in(PEL8514_D);
    	__vga_delay();
    	*green = (int) port_in(PEL8514_D);
    	__vga_delay();
    	*blue = (int) port_in(PEL8514_D);
	}
    /* select palette register */
    port_out(index, PEL_IR);

    /* read RGB components */
    __vga_delay();
    *red = (int) port_in(PEL_D);
    __vga_delay();
    *green = (int) port_in(PEL_D);
    __vga_delay();
    *blue = (int) port_in(PEL_D);

    return 0;  
}


int vga_setpalvec(int start, int num, int *pal)
{
    int j;

    /* select palette register */
    /* See above.. */
    if ((__svgalib_chipset == MACH32) && SVGAMODE(CM))
	{
	port_out(start, PEL8514_IW); 
	for(j = 0; j < num; j++)
	    {
	    if ((__svgalib_chipset == MACH32) && SVGAMODE(CM))
		{
		__vga_delay();
		port_out(*(pal++), PEL8514_D);
		__vga_delay();
		port_out(*(pal++), PEL8514_D);
		/* Uh yes.. and I didn't find a way to wait for hsync, so... */
		__vga_delay();
		port_out(*(pal++), PEL8514_D);
		}
	    }
	return j;
	}
    port_out(start, PEL_IW);

    for(j = 0; j < num; j++) {
        __vga_delay();
        port_out(*(pal++), PEL_D);
        __vga_delay();
        port_out(*(pal++), PEL_D);
	if (SCREENON) {		     /* writing the `blue' register will   */
	  while (!(inb(0x3da) & 1)); /* load the dac. Waiting for vertical */
	  while (inb(0x3da) & 1);    /* or horizontal retrace will load    */
 	} else			     /* the dac without disturbances       */	
	  __vga_delay();
        port_out(*(pal++), PEL_D);
    }

    return j;
}


int vga_getpalvec(int start, int num, int *pal)
{
    int j;

    if ((__svgalib_chipset == MACH32) && SVGAMODE(CM))
	{
	/* Actually the same but we are in 8514 mode and the dac
	   does not respond to the VGA circuitry anymore... */
	port_out(start, PEL8514_IR); 
    	for(j = 0; j < num; j++) {
            __vga_delay();
            *(pal++) = (int) port_in(PEL8514_D);
            __vga_delay();
            *(pal++) = (int) port_in(PEL8514_D);
            __vga_delay();
            *(pal++) = (int) port_in(PEL8514_D);
	    }
	return j;
	}

    /* select palette register */
    port_out(start, PEL_IR);

    for(j = 0; j < num; j++) {
        __vga_delay();
        *(pal++) = (int) port_in(PEL_D);
        __vga_delay();
        *(pal++) = (int) port_in(PEL_D);
        __vga_delay();
        *(pal++) = (int) port_in(PEL_D);
    }

    return j;
}



