dosbox-wii/src/hardware/vga_seq.cpp
2021-02-06 16:06:31 +01:00

161 lines
4.7 KiB
C++

/*
* Copyright (C) 2002-2019 The DOSBox Team
*
* 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
* GNU General Public License for more details.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "dosbox.h"
#include "inout.h"
#include "vga.h"
#define seq(blah) vga.seq.blah
Bitu read_p3c4(Bitu /*port*/,Bitu /*iolen*/) {
return seq(index);
}
void write_p3c4(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
seq(index)=val;
}
void write_p3c5(Bitu /*port*/,Bitu val,Bitu iolen) {
// LOG_MSG("SEQ WRITE reg %X val %X",seq(index),val);
switch(seq(index)) {
case 0: /* Reset */
seq(reset)=val;
break;
case 1: /* Clocking Mode */
if (val!=seq(clocking_mode)) {
// don't resize if only the screen off bit was changed
if ((val&(~0x20))!=(seq(clocking_mode)&(~0x20))) {
seq(clocking_mode)=val;
VGA_StartResize();
} else {
seq(clocking_mode)=val;
}
if (val & 0x20) vga.attr.disabled |= 0x2;
else vga.attr.disabled &= ~0x2;
}
/* TODO Figure this out :)
0 If set character clocks are 8 dots wide, else 9.
2 If set loads video serializers every other character
clock cycle, else every one.
3 If set the Dot Clock is Master Clock/2, else same as Master Clock
(See 3C2h bit 2-3). (Doubles pixels). Note: on some SVGA chipsets
this bit also affects the Sequencer mode.
4 If set loads video serializers every fourth character clock cycle,
else every one.
5 if set turns off screen and gives all memory cycles to the CPU
interface.
*/
break;
case 2: /* Map Mask */
seq(map_mask)=val & 15;
vga.config.full_map_mask=FillTable[val & 15];
vga.config.full_not_map_mask=~vga.config.full_map_mask;
/*
0 Enable writes to plane 0 if set
1 Enable writes to plane 1 if set
2 Enable writes to plane 2 if set
3 Enable writes to plane 3 if set
*/
break;
case 3: /* Character Map Select */
{
seq(character_map_select)=val;
Bit8u font1=(val & 0x3) << 1;
if (IS_VGA_ARCH) font1|=(val & 0x10) >> 4;
vga.draw.font_tables[0]=&vga.draw.font[font1*8*1024];
Bit8u font2=((val & 0xc) >> 1);
if (IS_VGA_ARCH) font2|=(val & 0x20) >> 5;
vga.draw.font_tables[1]=&vga.draw.font[font2*8*1024];
}
/*
0,1,4 Selects VGA Character Map (0..7) if bit 3 of the character
attribute is clear.
2,3,5 Selects VGA Character Map (0..7) if bit 3 of the character
attribute is set.
Note: Character Maps are placed as follows:
Map 0 at 0k, 1 at 16k, 2 at 32k, 3: 48k, 4: 8k, 5: 24k, 6: 40k, 7: 56k
*/
break;
case 4: /* Memory Mode */
/*
0 Set if in an alphanumeric mode, clear in graphics modes.
1 Set if more than 64kbytes on the adapter.
2 Enables Odd/Even addressing mode if set. Odd/Even mode places all odd
bytes in plane 1&3, and all even bytes in plane 0&2.
3 If set address bit 0-1 selects video memory planes (256 color mode),
rather than the Map Mask and Read Map Select Registers.
*/
seq(memory_mode)=val;
if (IS_VGA_ARCH) {
/* Changing this means changing the VGA Memory Read/Write Handler */
if (val&0x08) vga.config.chained=true;
else vga.config.chained=false;
VGA_SetupHandlers();
}
break;
default:
if (svga.write_p3c5) {
svga.write_p3c5(seq(index), val, iolen);
} else {
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index));
}
break;
}
}
Bitu read_p3c5(Bitu /*port*/,Bitu iolen) {
// LOG_MSG("VGA:SEQ:Read from index %2X",seq(index));
switch(seq(index)) {
case 0: /* Reset */
return seq(reset);
break;
case 1: /* Clocking Mode */
return seq(clocking_mode);
break;
case 2: /* Map Mask */
return seq(map_mask);
break;
case 3: /* Character Map Select */
return seq(character_map_select);
break;
case 4: /* Memory Mode */
return seq(memory_mode);
break;
default:
if (svga.read_p3c5)
return svga.read_p3c5(seq(index), iolen);
break;
}
return 0;
}
void VGA_SetupSEQ(void) {
if (IS_EGAVGA_ARCH) {
IO_RegisterWriteHandler(0x3c4,write_p3c4,IO_MB);
IO_RegisterWriteHandler(0x3c5,write_p3c5,IO_MB);
if (IS_VGA_ARCH) {
IO_RegisterReadHandler(0x3c4,read_p3c4,IO_MB);
IO_RegisterReadHandler(0x3c5,read_p3c5,IO_MB);
}
}
}