Use tables for ega page handler and lookup values.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@175
This commit is contained in:
parent
b9abeff3be
commit
bf747fff94
1 changed files with 56 additions and 96 deletions
|
@ -35,7 +35,8 @@ void VGA_ChainedWriteHandler(Bit32u start,Bit8u val) {
|
|||
};
|
||||
|
||||
|
||||
Bit8u VGA_NormalReadHandler(Bit32u start) {
|
||||
Bit8u VGA_NormalReadHandler(PhysPt start) {
|
||||
start-=0xa0000;
|
||||
vga.latch.d=vga.mem.latched[start].d;
|
||||
switch (vga.config.read_mode) {
|
||||
case 0:
|
||||
|
@ -49,7 +50,7 @@ Bit8u VGA_NormalReadHandler(Bit32u start) {
|
|||
}
|
||||
|
||||
//Nice one from DosEmu
|
||||
INLINE Bit32u RasterOp(Bit32u input,Bit32u mask) {
|
||||
INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) {
|
||||
switch (vga.config.raster_op) {
|
||||
case 0x00: /* None */
|
||||
return (input & mask) | (vga.latch.d & ~mask);
|
||||
|
@ -63,11 +64,39 @@ INLINE Bit32u RasterOp(Bit32u input,Bit32u mask) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
INLINE static Bit32u ModeOperation(Bit8u val) {
|
||||
Bit32u full;
|
||||
switch (vga.config.write_mode) {
|
||||
case 0x00:
|
||||
// Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
full=ExpandTable[val];
|
||||
full=(full & vga.config.full_not_enable_set_reset) | vga.config.full_enable_and_set_reset;
|
||||
full=RasterOp(full,vga.config.full_bit_mask);
|
||||
break;
|
||||
case 0x01:
|
||||
// Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode.
|
||||
full=vga.latch.d;
|
||||
break;
|
||||
case 0x02:
|
||||
//Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
full=RasterOp(FillTable[val&0xF],vga.config.full_bit_mask);
|
||||
break;
|
||||
case 0x03:
|
||||
// Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
full=RasterOp(vga.config.full_set_reset,ExpandTable[val] & vga.config.full_bit_mask);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("VGA:Unsupported write mode %d",vga.config.write_mode);
|
||||
}
|
||||
return full;
|
||||
}
|
||||
|
||||
Bit8u VGA_GFX_4_ReadHandler(Bit32u start) {
|
||||
return vga.mem.linear[start];
|
||||
}
|
||||
|
||||
void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val) {
|
||||
start-=0xa0000;
|
||||
vga.mem.linear[start]=val;
|
||||
Bitu line=start / 320;
|
||||
Bitu x=start % 320;
|
||||
|
@ -80,114 +109,45 @@ void VGA_GFX_4_WriteHandler(Bit32u start,Bit8u val) {
|
|||
}
|
||||
|
||||
void VGA_GFX_16_WriteHandler(Bit32u start,Bit8u val) {
|
||||
VGA_Latch new_latch;
|
||||
Bitu bit_mask;
|
||||
switch (vga.config.write_mode) {
|
||||
case 0x00:
|
||||
// Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
// val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate));
|
||||
//Todo could also include the rotation in the table :)
|
||||
new_latch.d=ExpandTable[val];
|
||||
{
|
||||
Bit32u resetmask=FillTable[vga.config.enable_set_reset];
|
||||
new_latch.d=(new_latch.d & ~resetmask) | ( FillTable[vga.config.set_reset] & resetmask);
|
||||
};
|
||||
new_latch.d=RasterOp(new_latch.d,vga.config.full_bit_mask);
|
||||
bit_mask=vga.gfx.bit_mask;
|
||||
break;
|
||||
case 0x01:
|
||||
// Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode.
|
||||
new_latch.d=vga.latch.d;
|
||||
bit_mask=0xff;
|
||||
break;
|
||||
case 0x02:
|
||||
//Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
new_latch.d=RasterOp(FillTable[val&0xF],vga.config.full_bit_mask);
|
||||
bit_mask=vga.gfx.bit_mask;
|
||||
break;
|
||||
case 0x03:
|
||||
// Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
new_latch.d=ExpandTable[val];
|
||||
new_latch.d&=vga.config.full_bit_mask; //Dunno would anyone use this seems a bit pointless
|
||||
bit_mask=new_latch.b[0];
|
||||
new_latch.d=RasterOp(FillTable[vga.config.set_reset],new_latch.d);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("VGA:Unsupported write mode %d",vga.config.write_mode);
|
||||
}
|
||||
start-=0xa0000;
|
||||
Bit32u data=ModeOperation(val);
|
||||
/* Update video memory and the pixel buffer */
|
||||
VGA_Latch pixels;
|
||||
pixels.d=vga.mem.latched[start].d;
|
||||
pixels.d&=~vga.config.full_map_mask;
|
||||
pixels.d|=(new_latch.d & vga.config.full_map_mask);
|
||||
pixels.d&=vga.config.full_not_map_mask;
|
||||
pixels.d|=(data & vga.config.full_map_mask);
|
||||
vga.mem.latched[start].d=pixels.d;
|
||||
Bit8u * write_pixels=&vga.buffer[start<<3];
|
||||
#if 1
|
||||
Bit8u sel=128;
|
||||
do {
|
||||
if (bit_mask & sel) {
|
||||
Bitu color;
|
||||
color=0;
|
||||
if (pixels.b[0] & sel) color|=1;
|
||||
if (pixels.b[1] & sel) color|=2;
|
||||
if (pixels.b[2] & sel) color|=4;
|
||||
if (pixels.b[3] & sel) color|=8;
|
||||
*write_pixels=color;
|
||||
*(write_pixels+512*1024)=color;
|
||||
|
||||
}
|
||||
write_pixels++;
|
||||
sel>>=1;
|
||||
} while (sel);
|
||||
#else
|
||||
#include "ega-switch.h"
|
||||
#endif
|
||||
Bit32u colors0_3, colors4_7;
|
||||
VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f;
|
||||
colors0_3 =
|
||||
Expand16Table[0][temp.b[0]] |
|
||||
Expand16Table[1][temp.b[1]] |
|
||||
Expand16Table[2][temp.b[2]] |
|
||||
Expand16Table[3][temp.b[3]];
|
||||
*(Bit32u *)write_pixels=colors0_3;
|
||||
*(Bit32u *)(write_pixels+512*1024)=colors0_3;
|
||||
temp.d=pixels.d & 0x0f0f0f0f;
|
||||
colors4_7 =
|
||||
Expand16Table[0][temp.b[0]] |
|
||||
Expand16Table[1][temp.b[1]] |
|
||||
Expand16Table[2][temp.b[2]] |
|
||||
Expand16Table[3][temp.b[3]];
|
||||
*(Bit32u *)(write_pixels+4)=colors4_7;
|
||||
*(Bit32u *)(write_pixels+512*1024+4)=colors4_7;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VGA_GFX_256U_WriteHandler(Bit32u start,Bit8u val) {
|
||||
VGA_Latch new_latch;
|
||||
switch (vga.config.write_mode) {
|
||||
case 0x00:
|
||||
/* This should be no problem with big or little endian */
|
||||
// Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
// val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate));
|
||||
//Todo could also include the rotation in the table :)
|
||||
new_latch.d=ExpandTable[val];
|
||||
{
|
||||
Bit32u resetmask=FillTable[vga.config.enable_set_reset];
|
||||
new_latch.d=(new_latch.d & ~resetmask) | ( FillTable[vga.config.set_reset] & resetmask);
|
||||
};
|
||||
new_latch.d=RasterOp(new_latch.d,vga.config.full_bit_mask);
|
||||
break;
|
||||
case 0x01:
|
||||
// Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode.
|
||||
new_latch.d=vga.latch.d;
|
||||
break;
|
||||
case 0x02:
|
||||
//TODO this mode also has Raster op
|
||||
//Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
new_latch.d=RasterOp(FillTable[val&0xF],vga.config.full_bit_mask);
|
||||
break;
|
||||
case 0x03:
|
||||
// Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
|
||||
new_latch.d=ExpandTable[val];
|
||||
new_latch.d&=vga.config.full_bit_mask; //Dunno would anyone use this seems a bit pointless
|
||||
new_latch.d=RasterOp(FillTable[vga.config.set_reset],new_latch.d);
|
||||
break;
|
||||
default:
|
||||
E_Exit("VGA:Unsupported write mode %d",vga.config.write_mode);
|
||||
}
|
||||
start-=0xa0000;
|
||||
Bit32u data=ModeOperation(val);
|
||||
VGA_Latch pixels;
|
||||
pixels.d=vga.mem.latched[start].d;
|
||||
pixels.d&=~vga.config.full_map_mask;
|
||||
pixels.d|=(new_latch.d & vga.config.full_map_mask);
|
||||
pixels.d&=vga.config.full_not_map_mask;
|
||||
pixels.d|=(data & vga.config.full_map_mask);
|
||||
vga.mem.latched[start].d=pixels.d;
|
||||
vga.mem.latched[start+64*1024].d=pixels.d;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue