dosbox-wii/src/hardware/vga_dac.cpp

217 lines
6.0 KiB
C++
Raw Normal View History

2009-05-02 23:03:37 +02:00
/*
2009-05-03 00:28:34 +02:00
* Copyright (C) 2002-2007 The DOSBox Team
2009-05-02 23:03:37 +02:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2009-05-03 00:02:15 +02:00
* GNU General Public License for more details.
2009-05-02 23:03:37 +02:00
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "dosbox.h"
#include "inout.h"
#include "render.h"
#include "vga.h"
/*
3C6h (R/W): PEL Mask
bit 0-7 This register is anded with the palette index sent for each dot.
Should be set to FFh.
3C7h (R): DAC State Register
bit 0-1 0 indicates the DAC is in Write Mode and 3 indicates Read mode.
3C7h (W): PEL Address Read Mode
bit 0-7 The PEL data register (0..255) to be read from 3C9h.
Note: After reading the 3 bytes at 3C9h this register will increment,
pointing to the next data register.
3C8h (R/W): PEL Address Write Mode
bit 0-7 The PEL data register (0..255) to be written to 3C9h.
Note: After writing the 3 bytes at 3C9h this register will increment, pointing
to the next data register.
3C9h (R/W): PEL Data Register
bit 0-5 Color value
Note: Each read or write of this register will cycle through first the
registers for Red, Blue and Green, then increment the appropriate
address register, thus the entire palette can be loaded by writing 0 to
the PEL Address Write Mode register 3C8h and then writing all 768 bytes
of the palette to this register.
*/
enum {DAC_READ,DAC_WRITE};
2009-05-03 00:28:34 +02:00
static INLINE void VGA_DAC_UpdateColor( Bitu index ) {
Bitu maskIndex = index & vga.dac.pel_mask;
RENDER_SetPal( index,
vga.dac.rgb[maskIndex].red << 2,
vga.dac.rgb[maskIndex].green << 2,
vga.dac.rgb[maskIndex].blue << 2
);
}
2009-05-02 23:03:37 +02:00
2009-05-03 00:02:15 +02:00
static void write_p3c6(Bitu port,Bitu val,Bitu iolen) {
2009-05-03 00:28:34 +02:00
if ( vga.dac.pel_mask != val ) {
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:DCA:Pel Mask set to %X", val);
vga.dac.pel_mask = val;
for ( Bitu i = 0;i<256;i++)
VGA_DAC_UpdateColor( i );
}
2009-05-02 23:12:18 +02:00
}
2009-05-03 00:02:15 +02:00
static Bitu read_p3c6(Bitu port,Bitu iolen) {
2009-05-02 23:12:18 +02:00
return vga.dac.pel_mask;
2009-05-02 23:03:37 +02:00
}
2009-05-03 00:02:15 +02:00
static void write_p3c7(Bitu port,Bitu val,Bitu iolen) {
2009-05-02 23:27:47 +02:00
vga.dac.read_index=val;
2009-05-02 23:03:37 +02:00
vga.dac.pel_index=0;
vga.dac.state=DAC_READ;
2009-05-03 00:18:08 +02:00
vga.dac.write_index= val + 1;
2009-05-02 23:43:00 +02:00
}
2009-05-03 00:02:15 +02:00
static Bitu read_p3c7(Bitu port,Bitu iolen) {
2009-05-02 23:43:00 +02:00
if (vga.dac.state==DAC_READ) return 0x3;
else return 0x0;
2009-05-02 23:03:37 +02:00
}
2009-05-03 00:02:15 +02:00
static void write_p3c8(Bitu port,Bitu val,Bitu iolen) {
2009-05-02 23:27:47 +02:00
vga.dac.write_index=val;
2009-05-02 23:03:37 +02:00
vga.dac.pel_index=0;
vga.dac.state=DAC_WRITE;
}
2009-05-03 00:18:08 +02:00
static Bitu read_p3c8(Bitu port, Bitu iolen){
return vga.dac.write_index;
}
2009-05-03 00:02:15 +02:00
static void write_p3c9(Bitu port,Bitu val,Bitu iolen) {
val&=0x3f;
2009-05-02 23:03:37 +02:00
switch (vga.dac.pel_index) {
case 0:
2009-05-02 23:27:47 +02:00
vga.dac.rgb[vga.dac.write_index].red=val;
2009-05-02 23:03:37 +02:00
vga.dac.pel_index=1;
break;
case 1:
2009-05-02 23:27:47 +02:00
vga.dac.rgb[vga.dac.write_index].green=val;
2009-05-02 23:03:37 +02:00
vga.dac.pel_index=2;
break;
case 2:
2009-05-02 23:27:47 +02:00
vga.dac.rgb[vga.dac.write_index].blue=val;
2009-05-02 23:03:37 +02:00
switch (vga.mode) {
2009-05-02 23:43:00 +02:00
case M_VGA:
case M_LIN8:
2009-05-03 00:28:34 +02:00
VGA_DAC_UpdateColor( vga.dac.write_index );
if ( GCC_UNLIKELY( vga.dac.pel_mask != 0xff)) {
Bitu index = vga.dac.write_index;
if ( (index & vga.dac.pel_mask) == index ) {
for ( Bitu i = index+1;i<256;i++)
if ( (i & vga.dac.pel_mask) == index )
VGA_DAC_UpdateColor( i );
}
}
2009-05-02 23:03:37 +02:00
break;
default:
/* Check for attributes and DAC entry link */
2009-05-02 23:27:47 +02:00
for (Bitu i=0;i<16;i++) {
2009-05-03 00:28:34 +02:00
if (vga.dac.combine[i]==vga.dac.write_index) {
2009-05-02 23:27:47 +02:00
RENDER_SetPal(i,
vga.dac.rgb[vga.dac.write_index].red << 2,
vga.dac.rgb[vga.dac.write_index].green << 2,
vga.dac.rgb[vga.dac.write_index].blue << 2);
}
2009-05-02 23:03:37 +02:00
}
}
2009-05-02 23:27:47 +02:00
vga.dac.write_index++;
2009-05-03 00:18:08 +02:00
// vga.dac.read_index = vga.dac.write_index - 1;//disabled as it breaks Wari
2009-05-02 23:03:37 +02:00
vga.dac.pel_index=0;
break;
default:
2009-05-02 23:43:00 +02:00
LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day
2009-05-03 00:37:32 +02:00
break;
2009-05-02 23:03:37 +02:00
};
}
2009-05-03 00:02:15 +02:00
static Bitu read_p3c9(Bitu port,Bitu iolen) {
2009-05-02 23:03:37 +02:00
Bit8u ret;
switch (vga.dac.pel_index) {
case 0:
2009-05-02 23:27:47 +02:00
ret=vga.dac.rgb[vga.dac.read_index].red;
2009-05-02 23:03:37 +02:00
vga.dac.pel_index=1;
break;
case 1:
2009-05-02 23:27:47 +02:00
ret=vga.dac.rgb[vga.dac.read_index].green;
2009-05-02 23:03:37 +02:00
vga.dac.pel_index=2;
break;
case 2:
2009-05-02 23:27:47 +02:00
ret=vga.dac.rgb[vga.dac.read_index].blue;
vga.dac.read_index++;
2009-05-02 23:03:37 +02:00
vga.dac.pel_index=0;
2009-05-03 00:18:08 +02:00
// vga.dac.write_index=vga.dac.read_index+1;//disabled as it breaks wari
2009-05-02 23:03:37 +02:00
break;
default:
2009-05-02 23:43:00 +02:00
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:DAC:Illegal Pel Index"); //If this can actually happen that will be the day
2009-05-03 00:37:32 +02:00
ret=0;
break;
2009-05-02 23:03:37 +02:00
}
return ret;
}
void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) {
/* Check if this is a new color */
2009-05-03 00:28:34 +02:00
vga.dac.combine[attr]=pal;
2009-05-02 23:43:00 +02:00
switch (vga.mode) {
case M_VGA:
case M_LIN8:
break;
default:
RENDER_SetPal(attr,
vga.dac.rgb[pal].red << 2,
vga.dac.rgb[pal].green << 2,
vga.dac.rgb[pal].blue << 2
2009-05-02 23:03:37 +02:00
);
2009-05-02 23:43:00 +02:00
}
2009-05-02 23:03:37 +02:00
}
2009-05-03 00:02:15 +02:00
void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) {
2009-05-03 00:28:34 +02:00
//Should only be called in machine != vga
2009-05-03 00:02:15 +02:00
vga.dac.rgb[entry].red=red;
vga.dac.rgb[entry].green=green;
vga.dac.rgb[entry].blue=blue;
for (Bitu i=0;i<16;i++)
2009-05-03 00:28:34 +02:00
if (vga.dac.combine[i]==entry)
2009-05-03 00:02:15 +02:00
RENDER_SetPal(i,red << 2,green << 2,blue << 2);
}
2009-05-02 23:03:37 +02:00
void VGA_SetupDAC(void) {
vga.dac.first_changed=256;
vga.dac.bits=6;
vga.dac.pel_mask=0xff;
vga.dac.pel_index=0;
vga.dac.state=DAC_READ;
2009-05-02 23:27:47 +02:00
vga.dac.read_index=0;
vga.dac.write_index=0;
2009-05-03 00:02:15 +02:00
if (machine==MCH_VGA) {
/* Setup the DAC IO port Handlers */
IO_RegisterWriteHandler(0x3c6,write_p3c6,IO_MB);
IO_RegisterReadHandler(0x3c6,read_p3c6,IO_MB);
IO_RegisterWriteHandler(0x3c7,write_p3c7,IO_MB);
IO_RegisterReadHandler(0x3c7,read_p3c7,IO_MB);
2009-05-03 00:18:08 +02:00
IO_RegisterReadHandler(0x3c8,read_p3c8,IO_MB);
2009-05-03 00:02:15 +02:00
IO_RegisterWriteHandler(0x3c8,write_p3c8,IO_MB);
IO_RegisterWriteHandler(0x3c9,write_p3c9,IO_MB);
IO_RegisterReadHandler(0x3c9,read_p3c9,IO_MB);
}
2009-05-02 23:03:37 +02:00
};