From b5c65f12a01d7fd56013ba67d26787a75cc6742f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Tue, 3 Jun 2008 18:35:32 +0000 Subject: [PATCH] better vga irq2 emulation/misc vga reg vret signalling (hal) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3168 --- src/hardware/vga_crtc.cpp | 7 ++++++- src/hardware/vga_draw.cpp | 21 ++++++++++++++------- src/hardware/vga_misc.cpp | 34 +++++++++++++++++++++++----------- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 70fce996..5b6c40d0 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_crtc.cpp,v 1.32 2008-03-30 18:02:23 qbix79 Exp $ */ +/* $Id: vga_crtc.cpp,v 1.33 2008-06-03 18:35:32 c2woody Exp $ */ #include #include "dosbox.h" @@ -220,6 +220,11 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { 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; /* diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index fd0ed78b..c745e2ce 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_draw.cpp,v 1.100 2008-05-28 20:43:13 qbix79 Exp $ */ +/* $Id: vga_draw.cpp,v 1.101 2008-06-03 18:35:32 c2woody Exp $ */ #include #include @@ -730,6 +730,13 @@ static void INLINE VGA_ChangesStart( void ) { } #endif +static void VGA_VertInterrupt(Bitu val) { + if ((!vga.draw.vret_triggered) && ((vga.crtc.vertical_retrace_end&0x30)==0x10)) { + vga.draw.vret_triggered=true; + if (GCC_UNLIKELY(machine==MCH_EGA)) PIC_ActivateIRQ(9); + } +} + static void VGA_DisplayStartLatch(Bitu val) { vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1); } @@ -750,6 +757,11 @@ static void VGA_VerticalTimer(Bitu val) { } else PIC_AddEvent( VGA_DisplayStartLatch,(float)flip_offset); PIC_AddEvent(VGA_PanningLatch,(float)vga.draw.delay.vrend); + // EGA: 82c435 datasheet: interrupt happens at display end + // VGA: checked with scope + // add a little amount of time to make sure the last drawpart has already fired + if (IS_EGAVGA_ARCH) PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005)); + if ( GCC_UNLIKELY( vga.draw.parts_left)) { if (!IS_VGA_ARCH || (svgaCard!=SVGA_None)) { LOG(LOG_VGAMISC,LOG_NORMAL)( "Parts left: %d", vga.draw.parts_left ); @@ -841,12 +853,7 @@ static void VGA_VerticalTimer(Bitu val) { #ifdef VGA_KEEP_CHANGES if (startaddr_changed) VGA_ChangesStart(); #endif - if (GCC_UNLIKELY(machine==MCH_EGA)) { - if (!(vga.crtc.vertical_retrace_end&0x20)) { - PIC_ActivateIRQ(2); - vga.draw.vret_triggered=true; - } - } + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0)); else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); //VGA_DrawPart( vga.draw.parts_lines ); diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index f20bbdcb..6e301705 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * Copyright (C) 2002-2008 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 @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga_misc.cpp,v 1.36 2007-12-10 22:11:13 c2woody Exp $ */ +/* $Id: vga_misc.cpp,v 1.37 2008-06-03 18:35:32 c2woody Exp $ */ #include "dosbox.h" #include "inout.h" @@ -135,16 +135,28 @@ static Bitu read_p3c8(Bitu port,Bitu iolen) { } static Bitu read_p3c2(Bitu port,Bitu iolen) { - if (GCC_UNLIKELY(machine==MCH_EGA)) { - Bitu retcode=0x60; - retcode |= (vga.draw.vret_triggered ? 0x80 : 0x00); - vga.draw.vret_triggered=false; - // ega colour monitor - if ((((vga.misc_output>>2)&3)==0) || (((vga.misc_output>>2)&3)==3)) retcode|=0x10; - return retcode; - } else { - return 0x70; + Bit8u retval=0; + + if (machine==MCH_EGA) retval = 0x0F; + else if (IS_VGA_ARCH) retval = 0x60; + if ((machine==MCH_VGA) || (((vga.misc_output>>2)&3)==0) || (((vga.misc_output>>2)&3)==3)) { + retval |= 0x10; } + + if (vga.draw.vret_triggered) retval |= 0x80; + return retval; + /* + 0-3 0xF on EGA, 0x0 on VGA + 4 Status of the switch selected by the Miscellaneous Output + Register 3C2h bit 2-3. Switch high if set. + (apparently always 1 on VGA) + 5 (EGA) Pin 19 of the Feature Connector (FEAT0) is high if set + 6 (EGA) Pin 17 of the Feature Connector (FEAT1) is high if set + (default differs by card, ET4000 sets them both) + 7 If set IRQ 2 has happened due to Vertical Retrace. + Should be cleared by IRQ 2 interrupt routine by clearing port 3d4h + index 11h bit 4. + */ } void VGA_SetupMisc(void) {