diff --git a/include/dos_inc.h b/include/dos_inc.h index fead4fd..e7cbd72 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.82 2009/10/04 14:28:06 c2woody Exp $ */ +/* $Id: dos_inc.h,v 1.83 2009/10/28 21:45:12 qbix79 Exp $ */ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H @@ -627,6 +627,7 @@ struct DOS_Block { RealPt dbcs; RealPt filenamechar; RealPt collatingseq; + RealPt upcase; Bit8u* country;//Will be copied to dos memory. resides in real mem Bit16u dpb; //Fake Disk parameter system using only the first entry so the drive letter matches } tables; diff --git a/include/vga.h b/include/vga.h index db51da4..9f4e20f 100644 --- a/include/vga.h +++ b/include/vga.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: vga.h,v 1.47 2009/06/29 18:43:33 c2woody Exp $ */ +/* $Id: vga.h,v 1.48 2009/11/03 21:06:59 h-a-l-9000 Exp $ */ #ifndef DOSBOX_VGA_H #define DOSBOX_VGA_H @@ -126,6 +126,7 @@ typedef struct { Bitu address_line_total; Bitu address_line; Bitu lines_total; + Bitu vblank_skip; Bitu lines_done; Bitu lines_scaled; Bitu split_line; diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 6274c25..c9b72cf 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.120 2009/10/04 14:28:07 c2woody Exp $ */ +/* $Id: dos.cpp,v 1.121 2009/10/28 21:45:12 qbix79 Exp $ */ #include #include @@ -69,6 +69,7 @@ static Bitu DOS_21Handler(void) { char name1[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; char name2[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII]; + switch (reg_ah) { case 0x00: /* Terminate Program */ DOS_Terminate(mem_readw(SegPhys(ss)+reg_sp+2),false,0); @@ -924,13 +925,18 @@ static Bitu DOS_21Handler(void) { reg_cx = 5; CALLBACK_SCF(false); break; + case 0x02: // Get pointer to uppercase table + mem_writeb(data + 0x00, reg_al); + mem_writed(data + 0x01, dos.tables.upcase); + reg_cx = 5; + CALLBACK_SCF(false); + break; case 0x06: // Get pointer to collating sequence table mem_writeb(data + 0x00, reg_al); mem_writed(data + 0x01, dos.tables.collatingseq); reg_cx = 5; CALLBACK_SCF(false); break; - case 0x02: // Get pointer to uppercase table case 0x03: // Get pointer to lowercase table case 0x04: // Get pointer to filename uppercase table case 0x07: // Get pointer to double byte char set table diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index ba8e118..34b541f 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.31 2009/05/27 09:15:41 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.32 2009/10/28 21:45:12 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -134,10 +134,15 @@ void DOS_SetupTables(void) { mem_writeb(Real2Phys(dos.tables.filenamechar)+0x15,0x3d); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x16,0x3b); mem_writeb(Real2Phys(dos.tables.filenamechar)+0x17,0x2c); - /* COLLATING SEQUENCE TABLE */ - dos.tables.collatingseq=RealMake(DOS_GetMemory(17),0); + /* COLLATING SEQUENCE TABLE + UPCASE TABLE*/ + // 256 bytes for col table, 128 for upcase, 4 for number of entries + dos.tables.collatingseq=RealMake(DOS_GetMemory(25),0); mem_writew(Real2Phys(dos.tables.collatingseq),0x100); for (i=0; i<256; i++) mem_writeb(Real2Phys(dos.tables.collatingseq)+i+2,i); + dos.tables.upcase=RealMake(dos.tables.collatingseq,258); + mem_writew(Real2Phys(dos.tables.upcase),0x80); + for (i=0; i<128; i++) mem_writeb(Real2Phys(dos.tables.upcase)+i+2,0x80+i); + /* Create a fake FCB SFT */ seg=DOS_GetMemory(4); diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 0801356..1588ef8 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: adlib.cpp,v 1.41 2009/05/16 08:29:05 harekiet Exp $ */ +/* $Id: adlib.cpp,v 1.42 2009/11/03 20:17:42 qbix79 Exp $ */ #include #include @@ -29,32 +29,6 @@ #include "mem.h" #include "dbopl.h" -/* - Thanks to vdmsound for nice simple way to implement this -*/ - -#ifdef _MSC_VER - /* Disable recurring warnings */ -# pragma warning ( disable : 4018 ) -# pragma warning ( disable : 4244 ) -#endif - - -#define logerror - - -struct __MALLOCPTR { - void* m_ptr; - - __MALLOCPTR(void) : m_ptr(NULL) { } - __MALLOCPTR(void* src) : m_ptr(src) { } - void* operator=(void* rhs) { return (m_ptr = rhs); } - operator int*() const { return (int*)m_ptr; } - operator int**() const { return (int**)m_ptr; } - operator char*() const { return (char*)m_ptr; } -}; - - namespace OPL2 { #include "opl.cpp" @@ -112,78 +86,6 @@ namespace OPL3 { }; } - -namespace old_OPL2 { - #define OPL2_INTERNAL_FREQ 3579545 // The OPL2 operates at ~3.6MHz - #define HAS_YM3812 1 - #include "fmopl.c" - - struct Handler : public Adlib::Handler { - virtual void WriteReg( Bit32u reg, Bit8u val ) { - OPLWriteReg( OPL_YM3812[ 0 ], reg, val ); - } - virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { - OPL_YM3812[ 0 ]->address = val; - return val; - } - - virtual void Generate( MixerChannel* chan, Bitu samples ) { - Bit16s buf[1024]; - while( samples > 0 ) { - Bitu todo = samples > 1024 ? 1024 : samples; - samples -= todo; - YM3812UpdateOne( 0, buf, todo ); - chan->AddSamples_m16( todo, buf ); - } - } - virtual void Init( Bitu rate ) { - if ( YM3812Init( 1, OPL2_INTERNAL_FREQ, rate )) { - E_Exit("Can't create OPL2 Emulator"); - }; - } - ~Handler() { - YM3812Shutdown(); - } - }; -} -#undef OSD_CPU_H -#undef TL_TAB_LEN - -namespace old_OPL3 { - #define OPL3_INTERNAL_FREQ 14318180 // The OPL3 operates at ~14.3MHz - #define HAS_YMF262 1 - #include "ymf262.c" - - struct Handler : public Adlib::Handler { - virtual void WriteReg( Bit32u reg, Bit8u val ) { - OPL3WriteReg( YMF262[0], reg, val ); - } - virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) { - OPL3Write( YMF262[0], port, val ); - return YMF262[0]->address; - } - virtual void Generate( MixerChannel* chan, Bitu samples ) { - Bit16s buf[2][1024]; - while( samples > 0 ) { - Bitu todo = samples > 1024 ? 1024 : samples; - samples -= todo; - YMF262UpdateOne( 0, buf[0], todo ); - chan->AddSamples_s16( todo, buf[0] ); - } - } - virtual void Init( Bitu rate ) { - if ( YMF262Init( 1, OPL3_INTERNAL_FREQ, rate )) { - E_Exit("Can't create OPL3 Emulator"); - }; - } - ~Handler() { - YMF262Shutdown(); - } - }; -} - - - #define RAW_SIZE 1024 @@ -736,13 +638,7 @@ Module::Module( Section* configuration ) : Module_base(configuration) { mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM"); mixerChan->SetScale( 2.0 ); - if (oplemu == "old") { - if ( oplmode == OPL_opl2 ) { - handler = new old_OPL2::Handler(); - } else { - handler = new old_OPL3::Handler(); - } - } else if (oplemu == "fast") { + if (oplemu == "fast") { handler = new DBOPL::Handler(); } else if (oplemu == "compat") { if ( oplmode == OPL_opl2 ) { diff --git a/src/hardware/serialport/libserial.cpp b/src/hardware/serialport/libserial.cpp index 4b1416d..83f4b3b 100644 --- a/src/hardware/serialport/libserial.cpp +++ b/src/hardware/serialport/libserial.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: libserial.cpp,v 1.3 2009/10/12 12:55:20 h-a-l-9000 Exp $ */ +/* $Id: libserial.cpp,v 1.4 2009/11/02 09:51:02 h-a-l-9000 Exp $ */ #include "libserial.h" @@ -254,7 +254,7 @@ bool SERIAL_setCommParameters(COMPORT port, } #endif -#if defined (LINUX) || defined (MACOSX) +#if defined (LINUX) || defined (MACOSX) || defined (BSD) #include // strlen #include diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 7e69f74..cb0a603 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.111 2009/09/10 17:44:57 h-a-l-9000 Exp $ */ +/* $Id: vga_draw.cpp,v 1.112 2009/11/03 21:06:59 h-a-l-9000 Exp $ */ #include #include @@ -787,6 +787,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) { if (IS_EGAVGA_ARCH) { vga.draw.split_line = (Bitu)((vga.config.line_compare+1)/vga.draw.lines_scaled); if ((svgaCard==SVGA_S3Trio) && (vga.config.line_compare==0)) vga.draw.split_line=0; + vga.draw.split_line -= vga.draw.vblank_skip; } else { vga.draw.split_line = 0x10000; // don't care } @@ -861,9 +862,14 @@ static void VGA_VerticalTimer(Bitu /*val*/) { #ifdef VGA_KEEP_CHANGES if (startaddr_changed) VGA_ChangesStart(); #endif + float draw_skip = 0.0; + if (GCC_UNLIKELY(vga.draw.vblank_skip)) { + draw_skip = (float)(vga.draw.delay.htotal * vga.draw.vblank_skip); + vga.draw.address += vga.draw.address_add * (vga.draw.vblank_skip/(vga.draw.address_line_total)); + } - 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); + if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip)); + else PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines); //VGA_DrawPart( vga.draw.parts_lines ); //PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,vga.draw.parts_lines); //PIC_AddEvent(VGA_DrawPart,(float)(vga.draw.delay.parts/2),vga.draw.parts_lines); //Else tearline in Tyrian and second reality @@ -947,6 +953,7 @@ void VGA_SetupDrawing(Bitu /*val*/) { float fps; Bitu clock; Bitu htotal, hdend, hbstart, hbend, hrstart, hrend; Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend; + Bitu vblank_skip; if (IS_EGAVGA_ARCH) { htotal = vga.crtc.horizontal_total; hdend = vga.crtc.horizontal_display_end; @@ -976,14 +983,15 @@ void VGA_SetupDrawing(Bitu /*val*/) { vbstart |= (vga.s3.ex_ver_overflow & 0x4) << 8; vrstart |= ((vga.crtc.overflow & 0x80) << 2); vrstart |= (vga.s3.ex_ver_overflow & 0x10) << 6; - vbend = vga.crtc.end_vertical_blanking & 0x3f; - } else { - vbend = vga.crtc.end_vertical_blanking & 0xf; + vbend = vga.crtc.end_vertical_blanking & 0x7f; + } else { // EGA + vbend = vga.crtc.end_vertical_blanking & 0x1f; } htotal += 2; vtotal += 2; hdend += 1; vdend += 1; + vbstart += 1; hbend = hbstart + ((hbend - hbstart) & 0x3F); hrend = vga.crtc.end_horizontal_retrace & 0x1f; @@ -998,9 +1006,11 @@ void VGA_SetupDrawing(Bitu /*val*/) { if ( !vrend) vrend = vrstart + 0xf + 1; else vrend = vrstart + vrend; - vbend = (vbend - vbstart) & 0x3f; - if ( !vbend) vbend = vbstart + 0x3f + 1; + vbend = (vbend - vbstart) & 0x7f; + if ( !vbend) vbend = vbstart + 0x7f + 1; else vbend = vbstart + vbend; + + vbend++; if (svga.get_clock) { clock = svga.get_clock(); @@ -1094,6 +1104,38 @@ void VGA_SetupDrawing(Bitu /*val*/) { // Start and End of vertical retrace pulse vga.draw.delay.vrstart = vrstart * vga.draw.delay.htotal; vga.draw.delay.vrend = vrend * vga.draw.delay.htotal; + + // Vertical blanking tricks + vblank_skip = 0; + if (IS_VGA_ARCH) { // others need more investigation + if (vbend > vtotal) { + // blanking wraps to the start of the screen + vblank_skip = vbend&0x7f; + + // on blanking wrap to 0, the first line is not blanked + // this is used by the S3 BIOS and other S3 drivers in some SVGA modes + if((vbend&0x7f)==1) vblank_skip = 0; + + // it might also cut some lines off the bottom + if(vbstart < vdend) { + vdend = vbstart; + } + LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip); + } else if (vbstart==1) { + // blanking is used to cut lines at the start of the screen + vblank_skip = vbend; + LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip); + } else if (vbstart < vdend) { + if(vbend < vdend) { + // the game wants a black bar somewhere on the screen + LOG(LOG_VGA,LOG_WARN)("Unsupported blanking: line %d-%d",vbstart,vbend); + } else { + // blanking is used to cut off some lines from the bottom + vdend = vbstart; + } + } + vdend -= vblank_skip; + } // Display end vga.draw.delay.vdend = vdend * vga.draw.delay.htotal; @@ -1155,9 +1197,8 @@ void VGA_SetupDrawing(Bitu /*val*/) { //Check to prevent useless black areas if (hbstart