- implement Tandy special 4-color palette handling
- remove 3d8/3d9 from PCJr mode (PCJr didn't have it) - update INT10 palette functions accordingly - add a level of indirection to Tandy and PCjr palette deconding to fix video recording with on-screen palette changes - enable line-by-line emulation for Tandy too - machine-specific implementation of the color when display is disabled (vgaonly too) - enable the light pen stub on all machines that it is documented for - mask off a bank-selection bit that is not used under a specific circumstance Fixes Alley Cat palette on PCJr, Gauntlet, Ghostbusters, Pirates! on Tandy, Video recording on Tandy/PCJr where the palette is changed on-screen Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3647
This commit is contained in:
parent
959ea1527f
commit
c2622359f9
5 changed files with 327 additions and 130 deletions
|
@ -140,7 +140,8 @@ static Bitu INT10_Handler(void) {
|
|||
reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
||||
break;
|
||||
case 0x10: /* Palette functions */
|
||||
if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x03))) break;
|
||||
if (!IS_EGAVGA_ARCH && (reg_al>0x02)) break;
|
||||
else if (!IS_VGA_ARCH && (reg_al>0x03)) break;
|
||||
switch (reg_al) {
|
||||
case 0x00: /* SET SINGLE PALETTE REGISTER */
|
||||
INT10_SetSinglePaletteRegister(reg_bl,reg_bh);
|
||||
|
|
|
@ -246,6 +246,7 @@ VideoModeBlock ModeList_OTHER[]={
|
|||
{ 0x008 ,M_TANDY16,160 ,200 ,20 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,56 ,127 ,40 ,100 ,0 },
|
||||
{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 },
|
||||
{ 0x00A ,M_CGA4 ,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 },
|
||||
//{ 0x00E ,M_TANDY16,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xA0000 ,0x10000 ,113 ,256 ,80 ,200 ,0 },
|
||||
{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 },
|
||||
};
|
||||
|
||||
|
@ -547,6 +548,11 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) {
|
|||
default:
|
||||
IO_WriteB(0x3de,0x0);break;
|
||||
}
|
||||
// write palette
|
||||
for(Bitu i = 0; i < 16; i++) {
|
||||
IO_WriteB(0x3da,i+0x10);
|
||||
IO_WriteB(0x3de,i);
|
||||
}
|
||||
//Clear extended mapping
|
||||
IO_WriteB(0x3da,0x5);
|
||||
IO_WriteB(0x3de,0x0);
|
||||
|
@ -587,8 +593,9 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) {
|
|||
|
||||
if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f;
|
||||
else color_select=0x30;
|
||||
IO_WriteB(0x3d9,color_select);
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
|
||||
INT10_SetColorSelect(1);
|
||||
INT10_SetBackgroundBorder(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,9 +35,44 @@ static INLINE void WriteTandyACTL(Bit8u creg,Bit8u val) {
|
|||
|
||||
void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) {
|
||||
switch (machine) {
|
||||
case TANDY_ARCH_CASE:
|
||||
case MCH_PCJR:
|
||||
reg&=0xf;
|
||||
IO_Read(VGAREG_TDY_RESET);
|
||||
WriteTandyACTL(reg+0x10,val);
|
||||
IO_Write(0x3da,0x0); // palette back on
|
||||
break;
|
||||
case MCH_TANDY:
|
||||
// TODO waits for vertical retrace
|
||||
switch(vga.mode) {
|
||||
case M_TANDY2:
|
||||
if (reg >= 0x10) break;
|
||||
else if (reg==1) reg = 0x1f;
|
||||
else reg |= 0x10;
|
||||
WriteTandyACTL(reg+0x10,val);
|
||||
break;
|
||||
case M_TANDY4: {
|
||||
if (CurMode->mode!=0x0a) {
|
||||
// Palette values are kept constand by the BIOS.
|
||||
// The four colors are mapped to special palette values by hardware.
|
||||
// 3D8/3D9 registers influence this mapping. We need to figure out
|
||||
// which entry is used for the requested color.
|
||||
if (reg > 3) break;
|
||||
if (reg != 0) { // 0 is assumed to be at 0
|
||||
Bit8u color_select=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
||||
reg = reg*2+8; // Green Red Brown
|
||||
if (color_select& 0x20) reg++; // Cyan Magenta White
|
||||
}
|
||||
WriteTandyACTL(reg+0x10,val);
|
||||
}
|
||||
// 4-color high resolution mode 0x0a isn't handled specially
|
||||
else WriteTandyACTL(reg+0x10,val);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WriteTandyACTL(reg+0x10,val);
|
||||
break;
|
||||
}
|
||||
IO_Write(0x3da,0x0); // palette back on
|
||||
break;
|
||||
case EGAVGA_ARCH_CASE:
|
||||
if (!IS_VGA_ARCH) reg&=0x1f;
|
||||
|
@ -266,14 +301,24 @@ void INT10_SetPelMask(Bit8u mask) {
|
|||
|
||||
void INT10_GetPelMask(Bit8u & mask) {
|
||||
mask=IO_Read(VGAREG_PEL_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
void INT10_SetBackgroundBorder(Bit8u val) {
|
||||
Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
||||
temp=(temp & 0xe0) | (val & 0x1f);
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp);
|
||||
if (machine == MCH_CGA || IS_TANDY_ARCH)
|
||||
IO_Write(0x3d9,temp);
|
||||
Bit8u color_select=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
||||
color_select=(color_select & 0xe0) | (val & 0x1f);
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
|
||||
|
||||
if (machine == MCH_CGA || machine == MCH_TANDY)
|
||||
IO_Write(0x3d9,color_select);
|
||||
else if (machine == MCH_PCJR) {
|
||||
IO_Read(VGAREG_TDY_RESET); // reset the flipflop
|
||||
if (vga.mode!=M_TANDY_TEXT) {
|
||||
IO_Write(VGAREG_TDY_ADDRESS, 0x10);
|
||||
IO_Write(VGAREG_PCJR_DATA, color_select&0xf);
|
||||
}
|
||||
IO_Write(VGAREG_TDY_ADDRESS, 0x2); // border color
|
||||
IO_Write(VGAREG_PCJR_DATA, color_select&0xf);
|
||||
}
|
||||
else if (IS_EGAVGA_ARCH) {
|
||||
val = ((val << 1) & 0x10) | (val & 0x7);
|
||||
/* Aways set the overscan color */
|
||||
|
@ -282,7 +327,7 @@ void INT10_SetBackgroundBorder(Bit8u val) {
|
|||
if (CurMode->mode <= 3)
|
||||
return;
|
||||
INT10_SetSinglePaletteRegister( 0, val );
|
||||
val = (temp & 0x10) | 2 | ((temp & 0x20) >> 5);
|
||||
val = (color_select & 0x10) | 2 | ((color_select & 0x20) >> 5);
|
||||
INT10_SetSinglePaletteRegister( 1, val );
|
||||
val+=2;
|
||||
INT10_SetSinglePaletteRegister( 2, val );
|
||||
|
@ -295,8 +340,31 @@ void INT10_SetColorSelect(Bit8u val) {
|
|||
Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
||||
temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0);
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp);
|
||||
if (machine == MCH_CGA || IS_TANDY_ARCH)
|
||||
if (machine == MCH_CGA || machine==MCH_TANDY)
|
||||
IO_Write(0x3d9,temp);
|
||||
else if (machine == MCH_PCJR) {
|
||||
switch(vga.mode) {
|
||||
case M_TANDY2:
|
||||
IO_Write(VGAREG_TDY_ADDRESS, 0x11);
|
||||
IO_Write(VGAREG_PCJR_DATA, val&1? 0xf:0);
|
||||
break;
|
||||
case M_TANDY4:
|
||||
for(Bit8u i = 0x11; i < 0x14; i++) {
|
||||
const Bit8u t4_table[] = {0,2,4,6, 0,3,5,0xf};
|
||||
IO_Write(VGAREG_TDY_ADDRESS, i);
|
||||
IO_Write(VGAREG_PCJR_DATA, t4_table[(i-0x10)+(val&1? 4:0)]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// 16-color modes: always write the same palette
|
||||
for(Bit8u i = 0x11; i < 0x20; i++) {
|
||||
IO_Write(VGAREG_TDY_ADDRESS, i);
|
||||
IO_Write(VGAREG_PCJR_DATA, i-0x10);
|
||||
}
|
||||
break;
|
||||
}
|
||||
IO_Write(VGAREG_TDY_ADDRESS, 0); // enable palette
|
||||
}
|
||||
else if (IS_EGAVGA_ARCH) {
|
||||
if (CurMode->mode <= 3) //Maybe even skip the total function!
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue