/* * Copyright (C) 2002-2004 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "dosbox.h" #include "inout.h" #include "vga.h" #define seq(blah) vga.seq.blah Bit8u read_p3c4(Bit32u port) { return seq(index); } void write_p3c4(Bit32u port,Bit8u val) { seq(index)=val; }; void write_p3c5(Bit32u port,Bit8u val) { if (seq(index)>0x8 && vga.s3.pll.lock!=0x6) return; // 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)) { seq(clocking_mode)=val; VGA_StartResize(); } /* 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) | ((val & 0x10) >> 2); vga.draw.font1_start=((font1&3) * 16*1024) + ((font1 > 4) ? (8*1024) : 0); Bit8u font2=((val & 0xc) >> 2) | ((val & 0x20) >> 3); vga.draw.font2_start=((font2&3) * 16*1024) + ((font2 > 4) ? (8*1024) : 0); } /* 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; /* 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; /* S3 specific group */ case 0x08: vga.s3.pll.lock=val; break; case 0x10: /* Memory PLL Data Low */ vga.s3.mclk.n=val & 0x1f; vga.s3.mclk.r=val >> 5; break; case 0x11: /* Memory PLL Data High */ vga.s3.mclk.m=val & 0x7f; break; case 0x12: /* Video PLL Data Low */ vga.s3.clk[3].n=val & 0x1f; vga.s3.clk[3].r=val >> 5; break; case 0x13: /* Video PLL Data High */ vga.s3.clk[3].m=val & 0x7f; break; case 0x15: vga.s3.pll.cmd=val; VGA_StartResize(); break; default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index)); }; }; Bit8u read_p3c5(Bit32u port) { // LOG_MSG("VGA:SEQ:Read from index %2X",seq(index)); if (seq(index)>0x8 && vga.s3.pll.lock!=0x6) return 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); /* S3 specific group */ case 0x08: /* PLL Unlock */ return vga.s3.pll.lock; case 0x10: /* Memory PLL Data Low */ return vga.s3.mclk.n || (vga.s3.mclk.r << 5); case 0x11: /* Memory PLL Data High */ return vga.s3.mclk.m; case 0x12: /* Video PLL Data Low */ return vga.s3.clk[3].n || (vga.s3.clk[3].r << 5); case 0x13: /* Video Data High */ return vga.s3.clk[3].m; case 0x15: return vga.s3.pll.cmd; default: LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Read from illegal index %2X",seq(index)); }; return 0; }; void VGA_SetupSEQ(void) { IO_RegisterWriteHandler(0x3c4,write_p3c4,"VGA:Sequencer Index"); IO_RegisterWriteHandler(0x3c5,write_p3c5,"VGA:Sequencer Data"); IO_RegisterReadHandler(0x3c4,read_p3c4,"VGA:Sequencer Index"); IO_RegisterReadHandler(0x3c5,read_p3c5,"VGA:Sequencer Data"); }