static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) {
	switch (vga.other.index) {
	case 0x00:		//Horizontal total
		if (vga.other.htotal ^ val) VGA_StartResize();
		vga.other.htotal=val;
		break;
	case 0x01:		//Horizontal displayed chars
		if (vga.other.hdend ^ val) VGA_StartResize();
		vga.other.hdend=val;
		break;
	case 0x02:		//Horizontal sync position
		vga.other.hsyncp=val;
		break;
	case 0x03:		//Horizontal sync width
		vga.other.hsyncw=val;
		break;
	case 0x04:		//Vertical total
		if (vga.other.vtotal ^ val) VGA_StartResize();
		vga.other.vtotal=val;
		break;
	case 0x05:		//Vertical display adjust
		if (vga.other.vadjust ^ val) VGA_StartResize();
		vga.other.vadjust=val;
		break;
	case 0x06:		//Vertical rows
		if (vga.other.vdend ^ val) VGA_StartResize();
		vga.other.vdend=val;
		break;
	case 0x07:		//Vertical sync position
		vga.other.vsyncp=val;
		break;
	case 0x09:		//Max scanline
		if (vga.other.max_scanline ^ val) VGA_StartResize();
		vga.other.max_scanline=val;
		break;
	case 0x0A:	/* Cursor Start Register */
		vga.draw.cursor.sline = val&0x1f;
		vga.draw.cursor.enabled = ((val & 0x60) != 0x20);
		break;
	case 0x0B:	/* Cursor End Register */
		vga.draw.cursor.eline = val&0x1f;
		break;
	case 0x0C:	/* Start Address High Register */
		vga.config.display_start=(vga.config.display_start & 0x00FF) | (val << 8);
		break;
	case 0x0D:	/* Start Address Low Register */
		vga.config.display_start=(vga.config.display_start & 0xFF00) | val;
		break;
	case 0x0E:	/*Cursor Location High Register */
		vga.config.cursor_start&=0x00ff;
		vga.config.cursor_start|=val << 8;
		break;
	case 0x0F:	/* Cursor Location Low Register */
		vga.config.cursor_start&=0xff00;
		vga.config.cursor_start|=val;
		break;
	default:
		LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Write %X to illegal index %x",val,vga.other.index);
	}
}
void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
	if (!vga.internal.attrindex) {
		attr(index)=val & 0x1F;
		vga.internal.attrindex=true;
		attr(enabled)=val & 0x20;
		/* 
			0-4	Address of data register to write to port 3C0h or read from port 3C1h
			5	If set screen output is enabled and the palette can not be modified,
				if clear screen output is disabled and the palette can be modified.
		*/
		return;
	} else {
		vga.internal.attrindex=false;
		switch (attr(index)) {
			/* Palette */
		case 0x00:		case 0x01:		case 0x02:		case 0x03:
		case 0x04:		case 0x05:		case 0x06:		case 0x07:
		case 0x08:		case 0x09:		case 0x0a:		case 0x0b:
		case 0x0c:		case 0x0d:		case 0x0e:		case 0x0f:
			if (!attr(enabled)) VGA_ATTR_SetPalette(attr(index),val);
			/*
				0-5	Index into the 256 color DAC table. May be modified by 3C0h index
				10h and 14h.
			*/
			break;
		case 0x10: /* Mode Control Register */
			if (!IS_VGA_ARCH) val&=0x1f;	// not really correct, but should do it
			if ((attr(mode_control) ^ val) & 0x80) {
				attr(mode_control)^=0x80;
				for (Bitu i=0;i<0x10;i++) {
					VGA_ATTR_SetPalette(i,vga.attr.palette[i]);
				}
			}
			if ((attr(mode_control) ^ val) & 0x08) {
				VGA_SetBlinking(val & 0x8);
			}
			if ((attr(mode_control) ^ val) & 0x04) {
				attr(mode_control)=val;
				VGA_DetermineMode();
				if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) VGA_StartResize();
			} else {
				attr(mode_control)=val;
				VGA_DetermineMode();
			}

			/*
				0	Graphics mode if set, Alphanumeric mode else.
				1	Monochrome mode if set, color mode else.
				2	9-bit wide characters if set.
					The 9th bit of characters C0h-DFh will be the same as
					the 8th bit. Otherwise it will be the background color.
				3	If set Attribute bit 7 is blinking, else high intensity.
				5	If set the PEL panning register (3C0h index 13h) is temporarily set
					to 0 from when the line compare causes a wrap around until the next
					vertical retrace when the register is automatically reloaded with
					the old value, else the PEL panning register ignores line compares.
				6	If set pixels are 8 bits wide. Used in 256 color modes.
				7	If set bit 4-5 of the index into the DAC table are taken from port
					3C0h index 14h bit 0-1, else the bits in the palette register are
					used.
			*/
			break;
		case 0x11:	/* Overscan Color Register */
			attr(overscan_color)=val;
			/* 0-5  Color of screen border. Color is defined as in the palette registers. */
			break;
		case 0x12:	/* Color Plane Enable Register */
			/* Why disable colour planes? */
			attr(color_plane_enable)=val;
			/* 
				0	Bit plane 0 is enabled if set.
				1	Bit plane 1 is enabled if set.
				2	Bit plane 2 is enabled if set.
				3	Bit plane 3 is enabled if set.
				4-5	Video Status MUX. Diagnostics use only.
					Two attribute bits appear on bits 4 and 5 of the Input Status
					Register 1 (3dAh). 0: Bit 2/0, 1: Bit 5/4, 2: bit 3/1, 3: bit 7/6
			*/
			break;
		case 0x13:	/* Horizontal PEL Panning Register */
			attr(horizontal_pel_panning)=val & 0xF;
			switch (vga.mode) {
			case M_TEXT:
				if ((val==0x7) && (svgaCard==SVGA_None)) vga.config.pel_panning=7;
				if (val>0x7) vga.config.pel_panning=0;
				else vga.config.pel_panning=val+1;
				break;
			case M_VGA:
			case M_LIN8:
				vga.config.pel_panning=(val & 0x7)/2;
				break;
			case M_LIN16:
			default:
				vga.config.pel_panning=(val & 0x7);
			}
			/*
				0-3	Indicates number of pixels to shift the display left
					Value  9bit textmode   256color mode   Other modes
					0          1               0              0
					1          2              n/a             1
					2          3               1              2
					3          4              n/a             3
					4          5               2              4
					5          6              n/a             5
					6          7               3              6
					7          8              n/a             7
					8          0              n/a            n/a
			*/
			break;
		case 0x14:	/* Color Select Register */
			if (!IS_VGA_ARCH) {
				attr(color_select)=0;
				break;
			}
			if (attr(color_select) ^ val) {
				attr(color_select)=val;
				for (Bitu i=0;i<0x10;i++) {
					VGA_ATTR_SetPalette(i,vga.attr.palette[i]);
				}
			}
			/*
				0-1	If 3C0h index 10h bit 7 is set these 2 bits are used as bits 4-5 of
					the index into the DAC table.
				2-3	These 2 bits are used as bit 6-7 of the index into the DAC table
					except in 256 color mode.
					Note: this register does not affect 256 color modes.
			*/
			break;
		default:
			if (svga.write_p3c0) {
				svga.write_p3c0(attr(index), val, iolen);
				break;
			}
			LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Write to unkown Index %2X",attr(index));
			break;
		}
	}
}
示例#3
0
static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
    switch (vga.other.index) {
    case 0x00:		//Horizontal total
        if (vga.other.htotal ^ val) VGA_StartResize();
        vga.other.htotal=(Bit8u)val;
        break;
    case 0x01:		//Horizontal displayed chars
        if (vga.other.hdend ^ val) VGA_StartResize();
        vga.other.hdend=(Bit8u)val;
        break;
    case 0x02:		//Horizontal sync position
        vga.other.hsyncp=(Bit8u)val;
        break;
    case 0x03:		//Horizontal sync width
        if (machine==MCH_TANDY) vga.other.vsyncw=(Bit8u)(val >> 4);
        else vga.other.vsyncw = 16; // The MC6845 has a fixed v-sync width of 16 lines
        vga.other.hsyncw=(Bit8u)(val & 0xf);
        break;
    case 0x04:		//Vertical total
        if (vga.other.vtotal ^ val) VGA_StartResize();
        vga.other.vtotal=(Bit8u)val;
        break;
    case 0x05:		//Vertical display adjust
        if (vga.other.vadjust ^ val) VGA_StartResize();
        vga.other.vadjust=(Bit8u)val;
        break;
    case 0x06:		//Vertical rows
        if (vga.other.vdend ^ val) VGA_StartResize();
        vga.other.vdend=(Bit8u)val;
        break;
    case 0x07:		//Vertical sync position
        vga.other.vsyncp=(Bit8u)val;
        break;
    case 0x09:		//Max scanline
        val &= 0x1f; // VGADOC says bit 0-3 but the MC6845 datasheet says bit 0-4
        if (vga.other.max_scanline ^ val) VGA_StartResize();
        vga.other.max_scanline=(Bit8u)val;
        break;
    case 0x0A:	/* Cursor Start Register */
        vga.other.cursor_start = (Bit8u)(val & 0x3f);
        vga.draw.cursor.sline = (Bit8u)(val&0x1f);
        vga.draw.cursor.enabled = ((val & 0x60) != 0x20);
        break;
    case 0x0B:	/* Cursor End Register */
        vga.other.cursor_end = (Bit8u)(val&0x1f);
        vga.draw.cursor.eline = (Bit8u)(val&0x1f);
        break;
    case 0x0C:	/* Start Address High Register */
        vga.config.display_start=(vga.config.display_start & 0x00FF) | (val << 8);
        break;
    case 0x0D:	/* Start Address Low Register */
        vga.config.display_start=(vga.config.display_start & 0xFF00) | val;
        break;
    case 0x0E:	/*Cursor Location High Register */
        vga.config.cursor_start&=0x00ff;
        vga.config.cursor_start|=((Bit8u)val) << 8;
        break;
    case 0x0F:	/* Cursor Location Low Register */
        vga.config.cursor_start&=0xff00;
        vga.config.cursor_start|=(Bit8u)val;
        break;
    case 0x10:	/* Light Pen High */
        vga.other.lightpen &= 0xff;
        vga.other.lightpen |= (val & 0x3f)<<8;		// only 6 bits
        break;
    case 0x11:	/* Light Pen Low */
        vga.other.lightpen &= 0xff00;
        vga.other.lightpen |= (Bit8u)val;
        break;
    default:
        LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Write %X to illegal index %x",val,vga.other.index);
    }
示例#4
0
void SetClock_PVGA1A(Bitu which,Bitu target) {
	if (which < 4) {
		pvga1a.clockFreq[which]=1000*target;
		VGA_StartResize();
	}
}
示例#5
0
void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) {
//	if((crtc(index)!=0xe)&&(crtc(index)!=0xf)) 
//		LOG_MSG("CRTC w #%2x val %2x",crtc(index),val);
	switch(crtc(index)) {
	case 0x00:	/* Horizontal Total Register */
		if (crtc(read_only)) break;
		crtc(horizontal_total)=val;
		/* 	0-7  Horizontal Total Character Clocks-5 */
		break;
	case 0x01:	/* Horizontal Display End Register */
		if (crtc(read_only)) break;
		if (val != crtc(horizontal_display_end)) {
			crtc(horizontal_display_end)=val;
			VGA_StartResize();
		}
		/* 	0-7  Number of Character Clocks Displayed -1 */
		break;
	case 0x02:	/* Start Horizontal Blanking Register */
		if (crtc(read_only)) break;
		crtc(start_horizontal_blanking)=val;
		/*	0-7  The count at which Horizontal Blanking starts */
		break;
	case 0x03:	/* End Horizontal Blanking Register */
		if (crtc(read_only)) break;
		crtc(end_horizontal_blanking)=val;
		/*
			0-4	Horizontal Blanking ends when the last 6 bits of the character
				counter equals this field. Bit 5 is at 3d4h index 5 bit 7.
			5-6	Number of character clocks to delay start of display after Horizontal
				Total has been reached.
			7	Access to Vertical Retrace registers if set. If clear reads to 3d4h
				index 10h and 11h access the Lightpen read back registers ??
		*/
		break;
	case 0x04:	/* Start Horizontal Retrace Register */
		if (crtc(read_only)) break;
		crtc(start_horizontal_retrace)=val;
		/*	0-7  Horizontal Retrace starts when the Character Counter reaches this value. */
		break;
	case 0x05:	/* End Horizontal Retrace Register */
		if (crtc(read_only)) break;
		crtc(end_horizontal_retrace)=val;
		/*
			0-4	Horizontal Retrace ends when the last 5 bits of the character counter
				equals this value.
			5-6	Number of character clocks to delay start of display after Horizontal
				Retrace.
			7	bit 5 of the End Horizontal Blanking count (See 3d4h index 3 bit 0-4)
		*/	
		break;
	case 0x06: /* Vertical Total Register */
		if (crtc(read_only)) break;
		if (val != crtc(vertical_total)) {
			crtc(vertical_total)=val;	
			VGA_StartResize();
		}
		/*	0-7	Lower 8 bits of the Vertical Total. Bit 8 is found in 3d4h index 7
				bit 0. Bit 9 is found in 3d4h index 7 bit 5.
			Note: For the VGA this value is the number of scan lines in the display -2.
		*/
		break;
	case 0x07:	/* Overflow Register */
		//Line compare bit ignores read only */
		vga.config.line_compare=(vga.config.line_compare & 0x6ff) | (val & 0x10) << 4;
		if (crtc(read_only)) break;
		if ((vga.crtc.overflow ^ val) & 0xd6) {
			crtc(overflow)=val;
			VGA_StartResize();
		} else crtc(overflow)=val;
		/*
			0  Bit 8 of Vertical Total (3d4h index 6)
			1  Bit 8 of Vertical Display End (3d4h index 12h)
			2  Bit 8 of Vertical Retrace Start (3d4h index 10h)
			3  Bit 8 of Start Vertical Blanking (3d4h index 15h)
			4  Bit 8 of Line Compare Register (3d4h index 18h)
			5  Bit 9 of Vertical Total (3d4h index 6)
			6  Bit 9 of Vertical Display End (3d4h index 12h)
			7  Bit 9 of Vertical Retrace Start (3d4h index 10h)
		*/
		break;
	case 0x08:	/* Preset Row Scan Register */
		crtc(preset_row_scan)=val;
		vga.config.hlines_skip=val&31;
		if (IS_VGA_ARCH) vga.config.bytes_skip=(val>>5)&3;
		else vga.config.bytes_skip=0;
//		LOG_DEBUG("Skip lines %d bytes %d",vga.config.hlines_skip,vga.config.bytes_skip);
		/*
			0-4	Number of lines we have scrolled down in the first character row.
				Provides Smooth Vertical Scrolling.b
			5-6	Number of bytes to skip at the start of scanline. Provides Smooth
				Horizontal Scrolling together with the Horizontal Panning Register
				(3C0h index 13h).
		*/
		break;
	case 0x09: /* Maximum Scan Line Register */
	{
		if (IS_VGA_ARCH) {
			vga.config.line_compare &= 0x5ff;
			vga.config.line_compare |= (val&0x40)<<3;
		} else if(machine==MCH_EGA) {
			val &= 0x7f; // EGA ignores the doublescan bit
			}
		Bit8u old = crtc(maximum_scan_line);
		crtc(maximum_scan_line) = val;

		if(!vga.draw.doublescan_merging) {
			if ((old ^ val) & 0x20) VGA_StartResize();
			vga.draw.address_line_total = (val &0x1F) + 1;
			if (val&0x80) vga.draw.address_line_total*=2;
		} else if ((old ^ val) & 0xbf)
				VGA_StartResize();
		/*
			0-4	Number of scan lines in a character row -1. In graphics modes this is
				the number of times (-1) the line is displayed before passing on to
				the next line (0: normal, 1: double, 2: triple...).
				This is independent of bit 7, except in CGA modes which seems to
				require this field to be 1 and bit 7 to be set to work.
			5	Bit 9 of Start Vertical Blanking
			6	Bit 9 of Line Compare Register
			7	Doubles each scan line if set. I.e. displays 200 lines on a 400 display.
		*/
		break;
	}
	case 0x0A:	/* Cursor Start Register */
		crtc(cursor_start)=val;
		vga.draw.cursor.sline=val&0x1f;
		if (IS_VGA_ARCH) vga.draw.cursor.enabled=!(val&0x20);
		else vga.draw.cursor.enabled=true;
		/*
			0-4	First scanline of cursor within character.
			5	Turns Cursor off if set
		*/
		break;
	case 0x0B:	/* Cursor End Register */
		crtc(cursor_end)=val;
		vga.draw.cursor.eline=val&0x1f;
		vga.draw.cursor.delay=(val>>5)&0x3;

		/* 
			0-4	Last scanline of cursor within character
			5-6	Delay of cursor data in character clocks.
		*/
		break;
	case 0x0C:	/* Start Address High Register */
		crtc(start_address_high)=val;
		vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8);
		/* 0-7  Upper 8 bits of the start address of the display buffer */
		page_flip_debug_notify();
		break;
	case 0x0D:	/* Start Address Low Register */
		crtc(start_address_low)=val;
		vga.config.display_start=(vga.config.display_start & 0xFFFF00)| val;
		/*	0-7	Lower 8 bits of the start address of the display buffer */
		page_flip_debug_notify();
		break;
	case 0x0E:	/*Cursor Location High Register */
		crtc(cursor_location_high)=val;
		vga.config.cursor_start&=0xff00ff;
		vga.config.cursor_start|=val << 8;
		/*	0-7  Upper 8 bits of the address of the cursor */
		break;
	case 0x0F:	/* Cursor Location Low Register */
//TODO update cursor on screen
		crtc(cursor_location_low)=val;
		vga.config.cursor_start&=0xffff00;
		vga.config.cursor_start|=val;
		/*	0-7  Lower 8 bits of the address of the cursor */
		break;
	case 0x10:	/* Vertical Retrace Start Register */
		crtc(vertical_retrace_start)=val;
		/*	
			0-7	Lower 8 bits of Vertical Retrace Start. Vertical Retrace starts when
			the line counter reaches this value. Bit 8 is found in 3d4h index 7
			bit 2. Bit 9 is found in 3d4h index 7 bit 7.
		*/
		break;
	case 0x11:	/* Vertical Retrace End Register */
		crtc(vertical_retrace_end)=val;
		
		if (IS_EGAVGA_ARCH && !(val & 0x10)) {
			vga.draw.vret_triggered=false;
			if (GCC_UNLIKELY(machine==MCH_EGA)) PIC_DeActivateIRQ(9);
		}
		if (IS_VGA_ARCH) crtc(read_only)=(val & 128)>0;
		else crtc(read_only)=false;
		/*
			0-3	Vertical Retrace ends when the last 4 bits of the line counter equals
				this value.
			4	if clear Clears pending Vertical Interrupts.
			5	Vertical Interrupts (IRQ 2) disabled if set. Can usually be left
				disabled, but some systems (including PS/2) require it to be enabled.
			6	If set selects 5 refresh cycles per scanline rather than 3.
			7	Disables writing to registers 0-7 if set 3d4h index 7 bit 4 is not
				affected by this bit.
		*/
		break;
	case 0x12:	/* Vertical Display End Register */
		if (val!=crtc(vertical_display_end)) {
			if (abs((Bits)val-(Bits)crtc(vertical_display_end))<3) {
				// delay small vde changes a bit to avoid screen resizing
				// if they are reverted in a short timeframe
				PIC_RemoveEvents(VGA_SetupDrawing);
				vga.draw.resizing=false;
				crtc(vertical_display_end)=val;
				VGA_StartResize(150);
			} else {
				crtc(vertical_display_end)=val;
				VGA_StartResize();
			}
		}
		/*
			0-7	Lower 8 bits of Vertical Display End. The display ends when the line
				counter reaches this value. Bit 8 is found in 3d4h index 7 bit 1.
			Bit 9 is found in 3d4h index 7 bit 6.
		*/
		break;
	case 0x13:	/* Offset register */
		crtc(offset)=val;
		vga.config.scan_len&=0x300;
		vga.config.scan_len|=val;
		VGA_CheckScanLength();
		/*
			0-7	Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for
				word mode and 8 for Double Word mode.
		*/
		break;
	case 0x14:	/* Underline Location Register */
		crtc(underline_location)=val;
		if (IS_VGA_ARCH) {
			//Byte,word,dword mode
			if ( crtc(underline_location) & 0x40 )
				vga.config.addr_shift = 2;
			else if ( crtc( mode_control) & 0x40 )
				vga.config.addr_shift = 0;
			else
				vga.config.addr_shift = 1;
		} else {
			vga.config.addr_shift = 1;
		}

		VGA_CheckScanLength();
		/*
			0-4	Position of underline within Character cell.
			5	If set memory address is only changed every fourth character clock.
			6	Double Word mode addressing if set
		*/
		break;
	case 0x15:	/* Start Vertical Blank Register */
		if (val!=crtc(start_vertical_blanking)) {
			crtc(start_vertical_blanking)=val;
			VGA_StartResize();
		}
		/* 
			0-7	Lower 8 bits of Vertical Blank Start. Vertical blanking starts when
				the line counter reaches this value. Bit 8 is found in 3d4h index 7
				bit 3.
		*/
		break;
	case 0x16:	/*  End Vertical Blank Register */
		if (val!=crtc(end_vertical_blanking)) {
			crtc(end_vertical_blanking)=val;
			VGA_StartResize();
		}
		/*
			0-6	Vertical blanking stops when the lower 7 bits of the line counter
				equals this field. Some SVGA chips uses all 8 bits!
				IBM actually says bits 0-7.
		*/
		break;
	case 0x17:	/* Mode Control Register */
		crtc(mode_control)=val;
		vga.tandy.line_mask = (~val) & 3;
		//Byte,word,dword mode
		if ( crtc(underline_location) & 0x40 )
			vga.config.addr_shift = 2;
		else if ( crtc( mode_control) & 0x40 )
			vga.config.addr_shift = 0;
		else
			vga.config.addr_shift = 1;

		if ( vga.tandy.line_mask ) {
			vga.tandy.line_shift = 13;
			vga.tandy.addr_mask = (1 << 13) - 1;
		} else {
			vga.tandy.addr_mask = ~0;
			vga.tandy.line_shift = 0;
		}
		VGA_CheckScanLength();

		//Should we really need to do a determinemode here?
//		VGA_DetermineMode();
		/*
			0	If clear use CGA compatible memory addressing system
				by substituting character row scan counter bit 0 for address bit 13,
				thus creating 2 banks for even and odd scan lines.
			1	If clear use Hercules compatible memory addressing system by
				substituting character row scan counter bit 1 for address bit 14,
				thus creating 4 banks.
			2	If set increase scan line counter only every second line.
			3	If set increase memory address counter only every other character clock.
			5	When in Word Mode bit 15 is rotated to bit 0 if this bit is set else
				bit 13 is rotated into bit 0.
			6	If clear system is in word mode. Addresses are rotated 1 position up
				bringing either bit 13 or 15 into bit 0.
			7	Clearing this bit will reset the display system until the bit is set again.
		*/
		break;
	case 0x18:	/* Line Compare Register */
		crtc(line_compare)=val;
		vga.config.line_compare=(vga.config.line_compare & 0x700) | val;
		/*
			0-7	Lower 8 bits of the Line Compare. When the Line counter reaches this
				value, the display address wraps to 0. Provides Split Screen
				facilities. Bit 8 is found in 3d4h index 7 bit 4.
				Bit 9 is found in 3d4h index 9 bit 6.
		*/
		break;
	default:
		if (svga.write_p3d5) {
			svga.write_p3d5(crtc(index), val, iolen);
		} else {
			LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write to unknown index %X",crtc(index));
		}
		break;
	}