Slight change in vga to support the new rendering
Added some hardware acceleration functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1818
This commit is contained in:
		
							parent
							
								
									9213fd5bd6
								
							
						
					
					
						commit
						ae2dd7711e
					
				
					 7 changed files with 761 additions and 30 deletions
				
			
		| 
						 | 
				
			
			@ -7,7 +7,7 @@ noinst_LIBRARIES = libhardware.a
 | 
			
		|||
libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \
 | 
			
		||||
                        memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \
 | 
			
		||||
			vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \
 | 
			
		||||
			vga_memory.cpp vga_misc.cpp vga_seq.cpp cmos.cpp disney.cpp \
 | 
			
		||||
			vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp cmos.cpp disney.cpp \
 | 
			
		||||
			gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -144,6 +144,7 @@ void VGA_Init(Section* sec) {
 | 
			
		|||
	VGA_SetupSEQ();
 | 
			
		||||
	VGA_SetupAttr();
 | 
			
		||||
	VGA_SetupOther();
 | 
			
		||||
	VGA_SetupXGA();
 | 
			
		||||
	VGA_SetClock(0,CLK_25);
 | 
			
		||||
	VGA_SetClock(1,CLK_28);
 | 
			
		||||
/* Generate tables */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,13 @@
 | 
			
		|||
 | 
			
		||||
#define crtc(blah) vga.crtc.blah
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void VGA_MapMMIO(void);
 | 
			
		||||
void VGA_UnmapMMIO(void);
 | 
			
		||||
 | 
			
		||||
void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen);
 | 
			
		||||
Bitu DEBUG_EnableDebugger(void);
 | 
			
		||||
 | 
			
		||||
void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen) {
 | 
			
		||||
	crtc(index)=val;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -325,6 +332,9 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) {
 | 
			
		|||
	case 0x39:	/* CR39 Register Lock 2 */
 | 
			
		||||
		vga.s3.reg_lock2=val;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x40:  /* CR40 System Config */
 | 
			
		||||
		vga.s3.reg_40 = val;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x43:	/* CR43 Extended Mode */
 | 
			
		||||
		vga.s3.reg_43=val & ~0x4;
 | 
			
		||||
		if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) {
 | 
			
		||||
| 
						 | 
				
			
			@ -338,6 +348,43 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) {
 | 
			
		|||
			(3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5
 | 
			
		||||
			are 0
 | 
			
		||||
		*/
 | 
			
		||||
	case 0x45:  /* Hardware cursor mode */
 | 
			
		||||
		vga.s3.hgc.curmode = val;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x46:
 | 
			
		||||
		vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8);
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x47:  /*  HGC orgX */
 | 
			
		||||
		vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x48:
 | 
			
		||||
		vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8);
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x49:  /*  HGC orgY */
 | 
			
		||||
		vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x4A:  /* HGC foreground stack */
 | 
			
		||||
		if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0;
 | 
			
		||||
		vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val;
 | 
			
		||||
		vga.s3.hgc.fstackpos++;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x4B:  /* HGC background stack */
 | 
			
		||||
		if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0;
 | 
			
		||||
		vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val;
 | 
			
		||||
		vga.s3.hgc.bstackpos++;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x4c:  /* HGC start address high byte*/
 | 
			
		||||
		vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8);
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x4d:  /* HGC start address low byte*/
 | 
			
		||||
		vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff);
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x4e:  /* HGC pattern start X */
 | 
			
		||||
		vga.s3.hgc.posx = val;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x4f:  /* HGC pattern start X */
 | 
			
		||||
		vga.s3.hgc.posy = val;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x51:	/* Extended System Control 2 */
 | 
			
		||||
		vga.s3.reg_51=val & 0xc0;		//Only store bits 6,7
 | 
			
		||||
		//TODO Display start
 | 
			
		||||
| 
						 | 
				
			
			@ -374,6 +421,18 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) {
 | 
			
		|||
			7	(not 864/964) Enable EPROM Write. If set enables flash memory write
 | 
			
		||||
				control to the BIOS ROM address
 | 
			
		||||
		*/
 | 
			
		||||
	case 0x53:
 | 
			
		||||
		if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) {
 | 
			
		||||
			/* Map or unmap MMIO */
 | 
			
		||||
			if ((val & 0x10) != 0) {
 | 
			
		||||
				LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000");
 | 
			
		||||
				VGA_MapMMIO();
 | 
			
		||||
			} else {
 | 
			
		||||
				VGA_UnmapMMIO();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		vga.s3.ext_mem_ctrl = val;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x55:	/* Extended Video DAC Control */
 | 
			
		||||
		vga.s3.reg_55=val;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -572,7 +631,7 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) {
 | 
			
		|||
		return 0x11;		
 | 
			
		||||
		//Trio 64 id
 | 
			
		||||
	case 0x2f:	/* Revision */
 | 
			
		||||
		return 0x80;
 | 
			
		||||
		return 0x00;
 | 
			
		||||
	case 0x30:	/* CR30 Chip ID/REV register */
 | 
			
		||||
		return 0xe0;		//Trio+ dual byte
 | 
			
		||||
		// Trio32/64 has 0xe0. extended
 | 
			
		||||
| 
						 | 
				
			
			@ -582,7 +641,8 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) {
 | 
			
		|||
	case 0x35:	/* CR35 CRT Register Lock */
 | 
			
		||||
		return vga.s3.reg_35|(vga.s3.bank & 0xf);
 | 
			
		||||
	case 0x36: /* CR36 Reset State Read 1 */
 | 
			
		||||
		return 0x8f;
 | 
			
		||||
		//return 0x8f;
 | 
			
		||||
		return 0x8e; /* PCI version */
 | 
			
		||||
		//2 Mb PCI and some bios settings
 | 
			
		||||
	case 0x37: /* Reset state read 2 */
 | 
			
		||||
		return 0x2b;
 | 
			
		||||
| 
						 | 
				
			
			@ -590,17 +650,29 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) {
 | 
			
		|||
		return vga.s3.reg_lock1;
 | 
			
		||||
	case 0x39: /* CR39 Register Lock 2 */
 | 
			
		||||
		return vga.s3.reg_lock2;
 | 
			
		||||
	case 0x40: /* CR40 system config */
 | 
			
		||||
		return vga.s3.reg_40;
 | 
			
		||||
	case 0x43:	/* CR43 Extended Mode */
 | 
			
		||||
		return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4);
 | 
			
		||||
	case 0x45:  /* Hardware cursor mode */
 | 
			
		||||
		vga.s3.hgc.bstackpos = 0;
 | 
			
		||||
		vga.s3.hgc.fstackpos = 0;
 | 
			
		||||
		return vga.s3.hgc.curmode;
 | 
			
		||||
	case 0x51:	/* Extended System Control 2 */
 | 
			
		||||
		return ((vga.config.display_start >> 16) & 3 ) |
 | 
			
		||||
				((vga.s3.bank & 0x30) >> 2) |
 | 
			
		||||
				((vga.config.scan_len & 0x300) >> 4) |
 | 
			
		||||
				vga.s3.reg_51;
 | 
			
		||||
	case 0x53:
 | 
			
		||||
		return vga.s3.ext_mem_ctrl;
 | 
			
		||||
	case 0x55:	/* Extended Video DAC Control */
 | 
			
		||||
		return vga.s3.reg_55;
 | 
			
		||||
	case 0x58:	/* Linear Address Window Control */
 | 
			
		||||
		return	vga.s3.reg_58;
 | 
			
		||||
	case 0x59:	/* Linear Address Window Position High */
 | 
			
		||||
		return (vga.s3.la_window >> 8);
 | 
			
		||||
	case 0x5a:	/* Linear Address Window Position Low */
 | 
			
		||||
		return (vga.s3.la_window & 0xff);
 | 
			
		||||
	case 0x5D:	/* Extended Horizontal Overflow */
 | 
			
		||||
		return vga.s3.ex_hor_overflow;
 | 
			
		||||
	case 0x5e:	/* Extended Vertical Overflow */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,25 +29,26 @@
 | 
			
		|||
typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line);
 | 
			
		||||
 | 
			
		||||
static VGA_Line_Handler VGA_DrawLine;
 | 
			
		||||
static Bit8u TempLine[1280];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		||||
	line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine;
 | 
			
		||||
	line*=8*1024;Bit32u * draw=(Bit32u *)TempLine;
 | 
			
		||||
	for (Bitu x=vga.draw.blocks;x>0;x--) {
 | 
			
		||||
		Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff;
 | 
			
		||||
		*draw++=CGA_2_Table[val >> 4];
 | 
			
		||||
		*draw++=CGA_2_Table[val & 0xf];
 | 
			
		||||
	}
 | 
			
		||||
	return RENDER_TempLine;
 | 
			
		||||
	return TempLine;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		||||
	line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine;
 | 
			
		||||
	line*=8*1024;Bit32u * draw=(Bit32u *)TempLine;
 | 
			
		||||
	for (Bitu x=0;x<vga.draw.blocks;x++) {
 | 
			
		||||
		Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff;
 | 
			
		||||
		*draw++=CGA_4_Table[val];
 | 
			
		||||
	}
 | 
			
		||||
	return RENDER_TempLine;
 | 
			
		||||
	return TempLine;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bit8u convert16[16]={
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +58,7 @@ static Bit8u convert16[16]={
 | 
			
		|||
 | 
			
		||||
static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		||||
	Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vidstart + (line * 8 * 1024)];
 | 
			
		||||
	Bit32u * draw=(Bit32u *)RENDER_TempLine;
 | 
			
		||||
	Bit32u * draw=(Bit32u *)TempLine;
 | 
			
		||||
	for (Bitu x=0;x<vga.draw.blocks;x++) {
 | 
			
		||||
		Bitu val1=*reader++;Bitu val2=*reader++;
 | 
			
		||||
		*draw++=(val1 & 0x0f) << 8  |
 | 
			
		||||
| 
						 | 
				
			
			@ -65,12 +66,12 @@ static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		|||
				(val2 & 0x0f) << 24 |
 | 
			
		||||
				(val2 & 0xf0) << 12;
 | 
			
		||||
	}
 | 
			
		||||
	return RENDER_TempLine;
 | 
			
		||||
	return TempLine;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		||||
	Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vidstart + (line * 8 * 1024)];
 | 
			
		||||
	Bit32u * draw=(Bit32u *)RENDER_TempLine;
 | 
			
		||||
	Bit32u * draw=(Bit32u *)TempLine;
 | 
			
		||||
	for (Bitu x=0;x<vga.draw.blocks;x++) {
 | 
			
		||||
		Bitu val1=*reader++;Bitu val2=*reader++;
 | 
			
		||||
		*draw++=(val1 & 0x0f) << 8  |
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +79,7 @@ static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		|||
				(val2 & 0x0f) << 24 |
 | 
			
		||||
				(val2 & 0xf0) << 12;
 | 
			
		||||
	}
 | 
			
		||||
	return RENDER_TempLine;
 | 
			
		||||
	return TempLine;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -89,10 +90,52 @@ static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		|||
	return &vga.mem.linear[vidstart*4+panning];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) {
 | 
			
		||||
	if(vga.s3.hgc.curmode & 0x1) {
 | 
			
		||||
		Bitu lineat = vidstart / 160;
 | 
			
		||||
		if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63))) {
 | 
			
		||||
			return VGA_Draw_VGA_Line(vidstart, panning, line);
 | 
			
		||||
		} else {
 | 
			
		||||
			memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), 640);
 | 
			
		||||
			/* Draw mouse cursor */
 | 
			
		||||
			Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy;
 | 
			
		||||
			if(moff>63) moff=moff-64;
 | 
			
		||||
			if(moff<0) moff+=64;
 | 
			
		||||
			Bitu xat = vga.s3.hgc.originx;
 | 
			
		||||
			Bitu m, mat;
 | 
			
		||||
			mat = vga.s3.hgc.posx;
 | 
			
		||||
 | 
			
		||||
			for(m=0;m<64;m++) {
 | 
			
		||||
				switch(vga.s3.hgc.mc[moff][mat]) {
 | 
			
		||||
					case 0:
 | 
			
		||||
						TempLine[xat] = vga.s3.hgc.backstack[0];
 | 
			
		||||
						break;
 | 
			
		||||
					case 1:
 | 
			
		||||
						TempLine[xat] = vga.s3.hgc.forestack[0];
 | 
			
		||||
						break;
 | 
			
		||||
					case 2:
 | 
			
		||||
						//Transparent
 | 
			
		||||
						break;
 | 
			
		||||
					case 3:
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				xat++;
 | 
			
		||||
				mat++;
 | 
			
		||||
				if(mat>63) mat=0;
 | 
			
		||||
			}
 | 
			
		||||
			return TempLine;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		/* HW Mouse not enabled, use the tried and true call */
 | 
			
		||||
		return VGA_Draw_VGA_Line(vidstart, panning, line);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static Bit32u FontMask[2]={0xffffffff,0x0};
 | 
			
		||||
static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		||||
	Bit32u * draw=(Bit32u *)RENDER_TempLine;
 | 
			
		||||
	Bit32u * draw=(Bit32u *)TempLine;
 | 
			
		||||
	Bit8u * vidmem=&vga.mem.linear[vidstart];
 | 
			
		||||
	for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
 | 
			
		||||
		Bitu chr=vidmem[cx*2];
 | 
			
		||||
| 
						 | 
				
			
			@ -111,12 +154,12 @@ static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
 | 
			
		|||
	if (font_addr>=0 && font_addr<vga.draw.blocks) {
 | 
			
		||||
		if (line<vga.draw.cursor.sline) goto skip_cursor;
 | 
			
		||||
		if (line>vga.draw.cursor.eline) goto skip_cursor;
 | 
			
		||||
		draw=(Bit32u *)&RENDER_TempLine[font_addr*8];
 | 
			
		||||
		draw=(Bit32u *)&TempLine[font_addr*8];
 | 
			
		||||
		Bit32u att=TXT_FG_Table[vga.mem.linear[vga.config.cursor_start*2+1]&0xf];
 | 
			
		||||
		*draw++=att;*draw++=att;
 | 
			
		||||
	}
 | 
			
		||||
skip_cursor:
 | 
			
		||||
	return RENDER_TempLine;
 | 
			
		||||
	return TempLine;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void VGA_VerticalDisplayEnd(Bitu val) {
 | 
			
		||||
| 
						 | 
				
			
			@ -128,11 +171,11 @@ static void VGA_HorizontalTimer(void) {
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void VGA_DrawPart(void) {
 | 
			
		||||
static void VGA_DrawPart(Bitu lines) {
 | 
			
		||||
	Bitu subline=0;Bitu vidofs=vga.config.real_start;
 | 
			
		||||
	Bit8u * draw=0;
 | 
			
		||||
	while (vga.draw.lines_left) {
 | 
			
		||||
		vga.draw.lines_left--;
 | 
			
		||||
	while (lines--) {
 | 
			
		||||
		vga.draw.lines_done++;
 | 
			
		||||
		Bit8u * data=VGA_DrawLine(vga.draw.address,vga.draw.panning,vga.draw.address_line);
 | 
			
		||||
		RENDER_DrawLine(data);
 | 
			
		||||
		vga.draw.address_line++;
 | 
			
		||||
| 
						 | 
				
			
			@ -140,14 +183,15 @@ static void VGA_DrawPart(void) {
 | 
			
		|||
			vga.draw.address_line=0;
 | 
			
		||||
			vga.draw.address+=vga.draw.address_add;
 | 
			
		||||
		}
 | 
			
		||||
		if (vga.draw.split_line==vga.draw.lines_left) {
 | 
			
		||||
		if (vga.draw.split_line==vga.draw.lines_done) {
 | 
			
		||||
			vga.draw.address=0;vga.draw.panning=0;
 | 
			
		||||
			vga.draw.address_line=0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	RENDER_EndUpdate();
 | 
			
		||||
//	vga.draw.parts_left--;
 | 
			
		||||
//	if (vga.draw.parts_left) PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts);
 | 
			
		||||
	vga.draw.parts_left--;
 | 
			
		||||
	if (vga.draw.parts_left) {
 | 
			
		||||
		PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines);
 | 
			
		||||
	} else RENDER_EndUpdate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void VGA_SetBlinking(Bitu enabled) {
 | 
			
		||||
| 
						 | 
				
			
			@ -169,11 +213,11 @@ static void VGA_VerticalTimer(Bitu val) {
 | 
			
		|||
	vga.config.retrace=false;
 | 
			
		||||
	PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal);
 | 
			
		||||
	PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend);
 | 
			
		||||
	vga.draw.parts_left=4;
 | 
			
		||||
	vga.draw.lines_left=vga.draw.lines_total;
 | 
			
		||||
	vga.draw.parts_left=vga.draw.parts_total;
 | 
			
		||||
	vga.draw.lines_done=0;
 | 
			
		||||
	vga.draw.address=vga.config.real_start;
 | 
			
		||||
	vga.draw.address_line=vga.config.hlines_skip;
 | 
			
		||||
	vga.draw.split_line=vga.draw.lines_total-(vga.config.line_compare/vga.draw.lines_scaled);
 | 
			
		||||
	vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled);
 | 
			
		||||
	vga.draw.panning=vga.config.pel_panning;
 | 
			
		||||
	switch (vga.mode) {
 | 
			
		||||
	case M_TEXT:
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +233,7 @@ static void VGA_VerticalTimer(Bitu val) {
 | 
			
		|||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	if (RENDER_StartUpdate()) {
 | 
			
		||||
		VGA_DrawPart();
 | 
			
		||||
		PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -310,7 +354,6 @@ void VGA_SetupDrawing(Bitu val) {
 | 
			
		|||
	Bitu width,height;
 | 
			
		||||
	Bitu scalew=1;
 | 
			
		||||
	Bitu scaleh=1;
 | 
			
		||||
 | 
			
		||||
	width=hdispend;
 | 
			
		||||
	height=vdispend;
 | 
			
		||||
	vga.draw.double_scan=false;
 | 
			
		||||
| 
						 | 
				
			
			@ -329,7 +372,12 @@ void VGA_SetupDrawing(Bitu val) {
 | 
			
		|||
		vga.draw.lines_scaled=scaleh;
 | 
			
		||||
		vga.draw.address_line_total=1;
 | 
			
		||||
		height/=scaleh;width<<=3;
 | 
			
		||||
		VGA_DrawLine=VGA_Draw_VGA_Line;
 | 
			
		||||
		/* Use HW mouse cursor drawer if enabled */
 | 
			
		||||
		if(vga.s3.hgc.curmode & 0x1) {
 | 
			
		||||
			VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse;
 | 
			
		||||
		} else {
 | 
			
		||||
			VGA_DrawLine=VGA_Draw_VGA_Line;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case M_EGA16:
 | 
			
		||||
		scaleh*=vga.draw.font_height;
 | 
			
		||||
| 
						 | 
				
			
			@ -419,6 +467,7 @@ void VGA_SetupDrawing(Bitu val) {
 | 
			
		|||
	};
 | 
			
		||||
	VGA_CheckScanLength();
 | 
			
		||||
	vga.draw.lines_total=height;
 | 
			
		||||
	vga.draw.parts_lines=vga.draw.lines_total/vga.draw.parts_total;
 | 
			
		||||
	if (( width != vga.draw.width) || (height != vga.draw.height)) {
 | 
			
		||||
		PIC_RemoveEvents(VGA_VerticalTimer);
 | 
			
		||||
		PIC_RemoveEvents(VGA_VerticalDisplayEnd);
 | 
			
		||||
| 
						 | 
				
			
			@ -428,7 +477,7 @@ void VGA_SetupDrawing(Bitu val) {
 | 
			
		|||
 | 
			
		||||
		LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, fps %f",width,height,fps);
 | 
			
		||||
		LOG(LOG_VGA,LOG_NORMAL)("Scalew %d, Scaleh %d aspect %f",scalew,scaleh,aspect_ratio);
 | 
			
		||||
		RENDER_SetSize(width,height,8,aspect_ratio,scalew,scaleh);
 | 
			
		||||
		RENDER_SetSize(width,height,8,aspect_ratio,scalew>1,scaleh>1);
 | 
			
		||||
		PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,7 +93,7 @@ static void write_p3cf(Bitu port,Bitu val,Bitu iolen) {
 | 
			
		|||
		break;
 | 
			
		||||
	case 5: /* Mode Register */
 | 
			
		||||
		if ((gfx(mode) ^ val) & 0xf0) {
 | 
			
		||||
			gfx(mode)=val;
 | 
			
		||||
		gfx(mode)=val;
 | 
			
		||||
			VGA_DetermineMode();
 | 
			
		||||
		} else gfx(mode)=val;
 | 
			
		||||
		vga.config.write_mode=val & 3;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,9 @@
 | 
			
		|||
#include "vga.h"
 | 
			
		||||
#include "paging.h"
 | 
			
		||||
#include "pic.h"
 | 
			
		||||
#include "inout.h"
 | 
			
		||||
 | 
			
		||||
void VGA_MapMMIO(void);
 | 
			
		||||
 | 
			
		||||
static Bitu VGA_NormalReadHandler(PhysPt start) {
 | 
			
		||||
	vga.latch.d=vga.mem.latched[start].d;
 | 
			
		||||
| 
						 | 
				
			
			@ -233,6 +236,7 @@ public:
 | 
			
		|||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VGA_MAP_PageHandler : public PageHandler {
 | 
			
		||||
public:
 | 
			
		||||
	VGA_MAP_PageHandler() {
 | 
			
		||||
| 
						 | 
				
			
			@ -244,6 +248,66 @@ public:
 | 
			
		|||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class VGA_MMIO_PageHandler : public PageHandler {
 | 
			
		||||
public:
 | 
			
		||||
	Bit16u regmem[16384];
 | 
			
		||||
 | 
			
		||||
	VGA_MMIO_PageHandler() {
 | 
			
		||||
		flags=PFLAG_NOCODE;
 | 
			
		||||
		//memset(®mem[0], 0, sizeof(regmem));
 | 
			
		||||
	}
 | 
			
		||||
	void writeb(PhysPt addr,Bitu val) {
 | 
			
		||||
		Bitu port = addr & 0xffff;
 | 
			
		||||
		if(port >= 0x82E8) IO_WriteB(port, val);
 | 
			
		||||
		LOG_MSG("MMIO: Write byte to %x with %x", addr, val);
 | 
			
		||||
	}
 | 
			
		||||
	void writew(PhysPt addr,Bitu val) {
 | 
			
		||||
		Bitu port = addr & 0xffff;
 | 
			
		||||
		if(port >= 0x82E8) IO_WriteW(port, val);
 | 
			
		||||
		if(port == 0x8118) IO_WriteW(0x9ae8, val);
 | 
			
		||||
		if(port <= 0x0020) {
 | 
			
		||||
			IO_WriteW(0xe2e8, val);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		LOG_MSG("MMIO: Write word to %x with %x", addr, val);	
 | 
			
		||||
	}
 | 
			
		||||
	void writed(PhysPt addr,Bitu val) {
 | 
			
		||||
		Bitu port = addr & 0xffff;
 | 
			
		||||
		if(port >= 0x82E8) IO_WriteD(port, val);
 | 
			
		||||
		if(port == 0x8100) {
 | 
			
		||||
			IO_WriteW(0x86e8, (val >> 16));
 | 
			
		||||
			IO_WriteW(0x82e8, (val & 0xffff));
 | 
			
		||||
		}
 | 
			
		||||
		if(port == 0x8148) {
 | 
			
		||||
			IO_WriteW(0x96e8, (val >> 16));
 | 
			
		||||
			IO_WriteW(0xbee8, (val & 0xffff));
 | 
			
		||||
		}
 | 
			
		||||
		if(port <= 0x0020) {
 | 
			
		||||
			IO_WriteW(0xe2e8, (val & 0xffff));
 | 
			
		||||
			IO_WriteW(0xe2e8, (val >> 16));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		LOG_MSG("MMIO: Write dword to %x with %x", addr, val);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Bitu readb(PhysPt addr) {
 | 
			
		||||
		LOG_MSG("MMIO: Read byte from %x", addr);
 | 
			
		||||
 | 
			
		||||
		return 0x00;
 | 
			
		||||
	}
 | 
			
		||||
	Bitu readw(PhysPt addr) {
 | 
			
		||||
		Bitu port = addr & 0xffff;
 | 
			
		||||
		if(port >= 0x82E8) return IO_ReadW(port);
 | 
			
		||||
		LOG_MSG("MMIO: Read word from %x", addr);
 | 
			
		||||
		return 0x00;
 | 
			
		||||
	}
 | 
			
		||||
	Bitu readd(PhysPt addr) {
 | 
			
		||||
		LOG_MSG("MMIO: Read dword from %x", addr);
 | 
			
		||||
		return 0x00;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class VGA_TANDY_PageHandler : public PageHandler {
 | 
			
		||||
public:
 | 
			
		||||
	VGA_TANDY_PageHandler() {
 | 
			
		||||
| 
						 | 
				
			
			@ -262,13 +326,14 @@ public:
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static struct {
 | 
			
		||||
static struct vg {
 | 
			
		||||
	VGA_RAM_PageHandler hram;
 | 
			
		||||
	VGA_MAP_PageHandler hmap;
 | 
			
		||||
	VGA_TEXT_PageHandler htext;
 | 
			
		||||
	VGA_TANDY_PageHandler htandy;
 | 
			
		||||
	VGA_256_PageHandler h256;
 | 
			
		||||
	VGA_16_PageHandler h16;
 | 
			
		||||
	VGA_MMIO_PageHandler mmio;
 | 
			
		||||
} vgaph;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -338,6 +403,9 @@ range_b800:
 | 
			
		|||
		MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.hram);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) && (vga.mode == M_LIN8)) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio);
 | 
			
		||||
 | 
			
		||||
	PAGING_ClearTLB();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -346,6 +414,7 @@ bool  lfb_update;
 | 
			
		|||
static void VGA_DoUpdateLFB(Bitu val) {
 | 
			
		||||
	lfb_update=false;
 | 
			
		||||
	MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]);
 | 
			
		||||
	LOG_MSG("LIN: Reconfiguing linear page address");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void VGA_StartUpdateLFB(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -355,6 +424,16 @@ void VGA_StartUpdateLFB(void) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void VGA_MapMMIO(void) {
 | 
			
		||||
	MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void VGA_UnmapMMIO(void) {
 | 
			
		||||
	//MEM_SetPageHandler(VGA_PAGE_A0, &ram_page_handler);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void VGA_SetupMemory() {
 | 
			
		||||
	memset((void *)&vga.mem,0,512*1024*4);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										530
									
								
								src/hardware/vga_xga.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										530
									
								
								src/hardware/vga_xga.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,530 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  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 <string.h>
 | 
			
		||||
#include "dosbox.h"
 | 
			
		||||
#include "inout.h"
 | 
			
		||||
#include "vga.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
struct XGAStatus {
 | 
			
		||||
	struct scissorreg {
 | 
			
		||||
		Bit16u x1, y1, x2, y2;
 | 
			
		||||
	} scissors;
 | 
			
		||||
 | 
			
		||||
	Bit32u readmask;
 | 
			
		||||
	Bit32u writemask;
 | 
			
		||||
 | 
			
		||||
	Bit32u forecolor;
 | 
			
		||||
	Bit32u backcolor;
 | 
			
		||||
 | 
			
		||||
	Bit16u foremix;
 | 
			
		||||
 | 
			
		||||
	Bit16u curx, cury;
 | 
			
		||||
	Bit16u destx, desty;
 | 
			
		||||
 | 
			
		||||
	Bit16u MIPcount;
 | 
			
		||||
	Bit16u MAPcount;
 | 
			
		||||
 | 
			
		||||
	Bit16u pix_cntl;
 | 
			
		||||
	Bit16u read_sel;
 | 
			
		||||
 | 
			
		||||
	struct XGA_WaitCmd {
 | 
			
		||||
		bool wait;
 | 
			
		||||
		Bit16u cmd;
 | 
			
		||||
		Bit16u curx, cury;
 | 
			
		||||
		Bit16u x1, y1, x2, y2;
 | 
			
		||||
	} waitcmd;
 | 
			
		||||
 | 
			
		||||
} xga;
 | 
			
		||||
 | 
			
		||||
Bit8u tmpvram[2048 * 1024];
 | 
			
		||||
 | 
			
		||||
void XGA_Write_Multifunc(Bitu val, Bitu len) {
 | 
			
		||||
	Bitu regselect = val >> 12;
 | 
			
		||||
	Bitu dataval = val & 0xfff;
 | 
			
		||||
	switch(regselect) {
 | 
			
		||||
		case 0:
 | 
			
		||||
			xga.MIPcount = dataval;
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			xga.scissors.y1 = dataval;
 | 
			
		||||
			break;
 | 
			
		||||
		case 2:
 | 
			
		||||
			xga.scissors.x1 = dataval;
 | 
			
		||||
			break;
 | 
			
		||||
		case 3:
 | 
			
		||||
			xga.scissors.y2 = dataval;
 | 
			
		||||
			break;
 | 
			
		||||
		case 4:
 | 
			
		||||
			xga.scissors.x2 = dataval;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xa:
 | 
			
		||||
			xga.pix_cntl = dataval;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xf:
 | 
			
		||||
			xga.read_sel = dataval;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG_MSG("XGA: Unhandled multifunction command %x", regselect);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_DrawPoint8(Bitu x, Bitu y, Bit8u c) {
 | 
			
		||||
	Bit32u memaddr = (y * 640) + x;
 | 
			
		||||
	vga.mem.linear[memaddr] = c;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Bit8u XGA_GetPoint8(Bitu x, Bitu y) {
 | 
			
		||||
	Bit32u memaddr = (y * 640) + x;
 | 
			
		||||
	return vga.mem.linear[memaddr];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_DrawPoint16(Bitu x, Bitu y, Bit16u c) {
 | 
			
		||||
	Bit16u *memptr;
 | 
			
		||||
	Bit32u memaddr = (y * 640) + x;
 | 
			
		||||
	memptr = (Bit16u *)&vga.mem.linear[memaddr];
 | 
			
		||||
	*memptr = c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_DrawRectangle(Bitu x1, Bitu y1, Bitu x2, Bitu y2) {
 | 
			
		||||
	Bit32u xat, yat;
 | 
			
		||||
	Bit32u xmass, xmod, xdist;
 | 
			
		||||
	Bit32u *memptr;
 | 
			
		||||
	Bit8u *smallptr;
 | 
			
		||||
	Bit32u c;
 | 
			
		||||
	Bit8u smallc;
 | 
			
		||||
 | 
			
		||||
	xdist = (x2 -x1);
 | 
			
		||||
	xmass = (xdist) & 0xfffffffb;
 | 
			
		||||
	xmod = (xdist) & 0x3;
 | 
			
		||||
 | 
			
		||||
	smallc = (xga.forecolor & 0xff);
 | 
			
		||||
	c = (smallc) | ((smallc) << 8) | ((smallc) << 16) | ((smallc) << 24);
 | 
			
		||||
 | 
			
		||||
	for(yat=y1;yat<=y2;yat++) {
 | 
			
		||||
		Bit32u memaddr = (yat * (Bit32u)640) + x1; 
 | 
			
		||||
		smallptr = &vga.mem.linear[memaddr];
 | 
			
		||||
		for(xat=0;xat<xdist;xat++) *smallptr++ = smallc;
 | 
			
		||||
	}
 | 
			
		||||
	/*
 | 
			
		||||
	for(yat=y1;yat<=y2;yat++) {
 | 
			
		||||
		Bit32u memaddr = (yat * (Bit32u)640) + x1;
 | 
			
		||||
		memptr = (Bit32u *)&vga.mem.linear[memaddr];
 | 
			
		||||
		for(xat=0;xat<xmass;xat+=4) *memptr++ = c;
 | 
			
		||||
		if(xmod!=0) {
 | 
			
		||||
			smallptr = (Bit8u *)memptr;
 | 
			
		||||
			for(xat=0;xat<xmod;xat++) *smallptr++ = smallc;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	*/
 | 
			
		||||
	LOG_MSG("XGA: Draw rect (%d, %d)-(%d, %d), %d", x1, y1, x2, y2, xga.forecolor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool XGA_CheckX(void) {
 | 
			
		||||
	bool newline = false;
 | 
			
		||||
	if(xga.waitcmd.curx > xga.waitcmd.x2) {
 | 
			
		||||
		xga.waitcmd.curx = xga.waitcmd.x1;
 | 
			
		||||
		xga.waitcmd.cury++;
 | 
			
		||||
		newline = true;
 | 
			
		||||
		if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false;
 | 
			
		||||
	}
 | 
			
		||||
	return newline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_DrawWait(Bitu val, Bitu len) {
 | 
			
		||||
	if(!xga.waitcmd.wait) return;
 | 
			
		||||
	Bitu mixmode = (xga.pix_cntl >> 6) & 0x3;
 | 
			
		||||
 | 
			
		||||
	switch(xga.waitcmd.cmd) {
 | 
			
		||||
		case 2: /* Rectangle */
 | 
			
		||||
			if(mixmode == 0) { /* FOREMIX always used */
 | 
			
		||||
				switch(len) {
 | 
			
		||||
					case 1:
 | 
			
		||||
						XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, val);
 | 
			
		||||
						break;
 | 
			
		||||
					case 2:
 | 
			
		||||
						XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val & 0xff));
 | 
			
		||||
						XGA_CheckX();
 | 
			
		||||
						XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val >> 8));
 | 
			
		||||
						break;
 | 
			
		||||
					case 4:
 | 
			
		||||
						XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val & 0xff));
 | 
			
		||||
						XGA_CheckX();
 | 
			
		||||
						XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 8) & 0xff));
 | 
			
		||||
						XGA_CheckX();
 | 
			
		||||
						XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 16) & 0xff));
 | 
			
		||||
						XGA_CheckX();
 | 
			
		||||
						XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 24) & 0xff));
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				XGA_CheckX();
 | 
			
		||||
			}
 | 
			
		||||
			if(mixmode == 2) { /* Data from PIX_TRANS selects the mix */
 | 
			
		||||
				Bitu bitcount;
 | 
			
		||||
				int i;
 | 
			
		||||
				switch(len) {
 | 
			
		||||
					case 1:
 | 
			
		||||
						bitcount = 8;
 | 
			
		||||
						break;
 | 
			
		||||
					case 2:
 | 
			
		||||
						bitcount = 16;
 | 
			
		||||
						val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);
 | 
			
		||||
						break;
 | 
			
		||||
					case 4:
 | 
			
		||||
						bitcount = 32;
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
 | 
			
		||||
				Bits bitneed = ((Bits)xga.waitcmd.x2 - (Bits)xga.waitcmd.x1) + 1;
 | 
			
		||||
				xga.waitcmd.curx = xga.waitcmd.x1;
 | 
			
		||||
				i = 15;
 | 
			
		||||
				for(;bitneed>=0;--bitneed) {
 | 
			
		||||
					Bitu bitval = (val >> i) & 0x1;
 | 
			
		||||
					//XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, i);
 | 
			
		||||
					if(bitval != 0) XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, xga.forecolor);
 | 
			
		||||
					--i;
 | 
			
		||||
					xga.waitcmd.curx++;
 | 
			
		||||
				}
 | 
			
		||||
				xga.waitcmd.cury++;
 | 
			
		||||
				
 | 
			
		||||
			
 | 
			
		||||
				if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG_MSG("XGA: Unhandled draw command %x", xga.waitcmd.cmd);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_BlitRect(Bitu val) {
 | 
			
		||||
	Bit32u xat, yat;
 | 
			
		||||
	Bit32u xmass, xmod, xdist, memrec;
 | 
			
		||||
	Bit8u *srcptr;
 | 
			
		||||
	Bit8u *destptr;
 | 
			
		||||
	Bit8u *destline;
 | 
			
		||||
	Bit8u *srcline;
 | 
			
		||||
 | 
			
		||||
	Bit32u c;
 | 
			
		||||
	Bit8u smallc;
 | 
			
		||||
	Bit8u tmpclr;
 | 
			
		||||
	bool incx = false;
 | 
			
		||||
	bool incy = false; 
 | 
			
		||||
 | 
			
		||||
	if((val >> 5) != 0) incx = true;
 | 
			
		||||
	if((val >> 7) != 0) incy = true;
 | 
			
		||||
 | 
			
		||||
	xdist = xga.MAPcount;
 | 
			
		||||
 | 
			
		||||
	smallc = (xga.forecolor & 0xff);
 | 
			
		||||
	memrec = 0;
 | 
			
		||||
	Bit32u srcaddr = (xga.cury * (Bit32u)640) + xga.curx;
 | 
			
		||||
	Bit32u destaddr = (xga.desty * (Bit32u)640) + xga.destx;
 | 
			
		||||
 | 
			
		||||
	srcptr = &vga.mem.linear[srcaddr];
 | 
			
		||||
	destptr = &vga.mem.linear[destaddr];
 | 
			
		||||
 | 
			
		||||
	/* Copy source to video ram */
 | 
			
		||||
	for(yat=0;yat<=xga.MIPcount ;yat++) {
 | 
			
		||||
		srcline = srcptr;
 | 
			
		||||
		destline = destptr;
 | 
			
		||||
		for(xat=0;xat<xga.MAPcount;xat++) {
 | 
			
		||||
			*destline = *srcline;
 | 
			
		||||
			//LOG_MSG("Copy (%d, %d) to (%d, %d)", sx, sy, tx, ty);
 | 
			
		||||
			if(incx) {
 | 
			
		||||
				destline++;
 | 
			
		||||
				srcline++;
 | 
			
		||||
			} else {
 | 
			
		||||
				--destline;
 | 
			
		||||
				--srcline;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if(incy) {
 | 
			
		||||
			srcptr+=640;
 | 
			
		||||
			destptr+=640;
 | 
			
		||||
		} else {
 | 
			
		||||
			srcptr-=640;
 | 
			
		||||
			destptr-=640;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LOG_MSG("XGA: Blit (%d, %d)-(%d, %d) to (%d, %d)-(%d, %d), incx %d, incy %d", xga.curx, xga.cury, xga.curx + xdist, xga.cury + xga.MIPcount, xga.destx, xga.desty, xga.destx + xdist, xga.desty + xga.MIPcount, incx, incy);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_DrawPattern(void) {
 | 
			
		||||
	Bit32u xat, yat, y1, y2, sx, sy, addx, addy;
 | 
			
		||||
	Bit32u xmass, xmod, xdist;
 | 
			
		||||
	Bit32u *memptr;
 | 
			
		||||
	Bit8u *smallptr;
 | 
			
		||||
	Bit8u smallc;
 | 
			
		||||
 | 
			
		||||
	y1 = xga.desty;
 | 
			
		||||
	y2 = xga.desty + xga.MIPcount;
 | 
			
		||||
	xdist = xga.MAPcount;
 | 
			
		||||
	sx = xga.curx;
 | 
			
		||||
	sy = xga.cury;
 | 
			
		||||
	addx = 0;
 | 
			
		||||
	addy = 0;
 | 
			
		||||
 | 
			
		||||
	for(yat=y1;yat<=y2;yat++) {
 | 
			
		||||
		Bit32u memaddr = (yat * (Bit32u)640) + xga.destx;
 | 
			
		||||
		smallptr = &vga.mem.linear[memaddr];
 | 
			
		||||
		for(xat=0;xat<xdist;xat++) {
 | 
			
		||||
			*smallptr++ = XGA_GetPoint8(sx + addx, sy + addy);
 | 
			
		||||
			addx++;
 | 
			
		||||
			if(addx>7) addx=0;
 | 
			
		||||
		}
 | 
			
		||||
		addy++;
 | 
			
		||||
		if(addy>7) addy=0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_DrawCmd(Bitu val, Bitu len) {
 | 
			
		||||
	Bit16u cmd;
 | 
			
		||||
	cmd = val >> 13;
 | 
			
		||||
	LOG_MSG("XGA: Draw command %x", cmd);
 | 
			
		||||
	switch(cmd) {
 | 
			
		||||
		case 2: /* Rectangle fill */
 | 
			
		||||
			if((val & 0x100) == 0) {
 | 
			
		||||
				xga.waitcmd.wait = false;
 | 
			
		||||
				XGA_DrawRectangle(xga.curx, xga.cury, xga.curx + xga.MAPcount, xga.cury + xga.MIPcount);
 | 
			
		||||
			} else {
 | 
			
		||||
				xga.waitcmd.wait = true;
 | 
			
		||||
				xga.waitcmd.curx = xga.curx;
 | 
			
		||||
				xga.waitcmd.cury = xga.cury;
 | 
			
		||||
				xga.waitcmd.x1 = xga.curx;
 | 
			
		||||
				xga.waitcmd.y1 = xga.cury;
 | 
			
		||||
				xga.waitcmd.x2 = xga.curx + xga.MAPcount;
 | 
			
		||||
				xga.waitcmd.y2 = xga.cury + xga.MIPcount;
 | 
			
		||||
				xga.waitcmd.cmd = 2;
 | 
			
		||||
				LOG_MSG("XGA: Draw wait rect (%d, %d)-(%d, %d)", xga.waitcmd.x1, xga.waitcmd.y1, xga.waitcmd.x2, xga.waitcmd.y2);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case 6: /* BitBLT */
 | 
			
		||||
			XGA_BlitRect(val);
 | 
			
		||||
			break;
 | 
			
		||||
		case 7: /* Pattern fill */
 | 
			
		||||
			XGA_DrawPattern();
 | 
			
		||||
			LOG_MSG("XGA: Pattern fill (%d, %d)-(%d, %d) to (%d, %d)-(%d, %d)", xga.curx, xga.cury, xga.curx + 8, xga.cury + 8, xga.destx, xga.desty, xga.destx + xga.MAPcount, xga.desty + xga.MIPcount);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG_MSG("XGA: Unhandled draw command %x", cmd);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_Write(Bitu port, Bitu val, Bitu len) {
 | 
			
		||||
	switch(port) {
 | 
			
		||||
		case 0x96e8:
 | 
			
		||||
			xga.MAPcount = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0x9ae8:
 | 
			
		||||
			XGA_DrawCmd(val, len);
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xa2e8:
 | 
			
		||||
			xga.backcolor = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xa6e8:
 | 
			
		||||
			xga.forecolor = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xaae8:
 | 
			
		||||
			xga.writemask = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xaee8:
 | 
			
		||||
			xga.readmask = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0x82e8:
 | 
			
		||||
			xga.cury = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0x86e8:
 | 
			
		||||
			xga.curx = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0x8ae8:
 | 
			
		||||
			xga.desty = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0x8ee8:
 | 
			
		||||
			xga.destx = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xbae8:
 | 
			
		||||
			xga.foremix = val;
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xbee8:
 | 
			
		||||
			XGA_Write_Multifunc(val, len);
 | 
			
		||||
			break;
 | 
			
		||||
		case 0xe2e8:
 | 
			
		||||
			XGA_DrawWait(val, len);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG_MSG("XGA: Wrote to port %x with %x, len %x", port, val, len);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Bitu XGA_Read(Bitu port, Bitu len) {
 | 
			
		||||
	LOG_MSG("XGA: Read from port %x, len %x", port, len);
 | 
			
		||||
	switch(port) {
 | 
			
		||||
		case 0x9ae8:
 | 
			
		||||
			return 0x0;
 | 
			
		||||
		case 0x9ae9:
 | 
			
		||||
			if(xga.waitcmd.wait) {
 | 
			
		||||
				return 0x4;
 | 
			
		||||
			} else {
 | 
			
		||||
				return 0x0;
 | 
			
		||||
			}
 | 
			
		||||
		case 0xa2e8:
 | 
			
		||||
			return xga.backcolor;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG_MSG("XGA: Read from port %x, len %x", port, len);
 | 
			
		||||
			return 0x0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XGA_UpdateHWC(void) {
 | 
			
		||||
	Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024;
 | 
			
		||||
	Bits x, y, t, m, xat, r, z;
 | 
			
		||||
	x = vga.s3.hgc.originx;
 | 
			
		||||
	y = vga.s3.hgc.originy;
 | 
			
		||||
	Bit16u bitsA, bitsB;
 | 
			
		||||
	Bit16u ab, bb;
 | 
			
		||||
	
 | 
			
		||||
	/* Read mouse cursor */
 | 
			
		||||
	for(t=0;t<64;t++) {
 | 
			
		||||
		xat = 0;
 | 
			
		||||
		for(m=0;m<4;m++) {
 | 
			
		||||
            bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr];
 | 
			
		||||
			mouseaddr+=2;
 | 
			
		||||
			bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr];
 | 
			
		||||
			mouseaddr+=2;
 | 
			
		||||
			z = 7;
 | 
			
		||||
			for(r=15;r>=0;--r) {
 | 
			
		||||
				vga.s3.hgc.mc[t][xat] = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1);
 | 
			
		||||
				xat++;
 | 
			
		||||
				--z;
 | 
			
		||||
				if(z<0) z=15;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void VGA_SetupXGA(void) {
 | 
			
		||||
	if (machine!=MCH_VGA) return;
 | 
			
		||||
 | 
			
		||||
	memset(&xga, 0, sizeof(XGAStatus));
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x42e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x42e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x46e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0x4ae8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	
 | 
			
		||||
	IO_RegisterWriteHandler(0x82e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x82e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0x82e9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x82e9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x86e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x86e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0x86e9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x86e9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x8ae8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x8ae8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x8ee8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x8ee8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0x8ee9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x8ee9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x92e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x92e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0x92e9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x92e9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x96e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x96e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0x96e9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x96e9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x9ae8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x9ae8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0x9ae9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x9ae9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0x9ee8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x9ee8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0x9ee9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0x9ee9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xa2e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xa2e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xa6e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xa6e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0xa6e9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xa6e9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xaae8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xaae8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0xaae9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xaae9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xaee8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xaee8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0xaee9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xaee9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xb2e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xb2e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0xb2e9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xb2e9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xb6e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xb6e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xbee8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xbee8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0xbee9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xbee9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xbae8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xbae8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterWriteHandler(0xbae9,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xbae9,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xe2e8,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xe2e8,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
	IO_RegisterWriteHandler(0xe2ea,&XGA_Write,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
	IO_RegisterReadHandler(0xe2ea,&XGA_Read,IO_MB | IO_MW | IO_MD);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue