From 022766bc739938458569f60c7dc6015ad58659a6 Mon Sep 17 00:00:00 2001 From: dborth Date: Tue, 19 May 2009 08:04:45 +0000 Subject: [PATCH] sync to dosbox svn --- src/hardware/adlib.cpp | 27 ++-- src/hardware/dbopl.cpp | 297 ++++++++++++++++++++++--------------- src/hardware/dbopl.h | 54 ++++--- src/hardware/disney.cpp | 43 +++++- src/hardware/fmopl.c | 1 - src/hardware/ipx.cpp | 5 +- src/hardware/mixer.cpp | 20 +-- src/hardware/opl.cpp | 35 +++-- src/hardware/opl.h | 9 +- src/hardware/pcspeaker.cpp | 22 ++- src/hardware/vga_dac.cpp | 42 ++---- src/ints/ems.cpp | 40 +++-- src/libs/gui_tk/gui_tk.h | 8 +- 13 files changed, 359 insertions(+), 244 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index bf356e8..0801356 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.38 2009/04/28 21:48:24 harekiet Exp $ */ +/* $Id: adlib.cpp,v 1.41 2009/05/16 08:29:05 harekiet Exp $ */ #include #include @@ -530,8 +530,8 @@ void Module::DualWrite( Bit8u index, Bit8u reg, Bit8u val ) { if ( chip[index].Write( reg, val ) ) return; //Enabling panning - if ( reg >= 0xc0 && reg <0xc8 ) { - val &= 7; + if ( reg >= 0xc0 && reg <=0xc8 ) { + val &= 0x0f; val |= index ? 0xA0 : 0x50; } Bit32u fullReg = reg + (index ? 0x100 : 0); @@ -729,6 +729,9 @@ Module::Module( Section* configuration ) : Module_base(configuration) { Section_prop * section=static_cast(configuration); Bitu base = section->Get_hex("sbbase"); Bitu rate = section->Get_int("oplrate"); + //Make sure we can't select lower than 8000 to prevent fixed point issues + if ( rate < 8000 ) + rate = 8000; std::string oplemu( section->Get_string( "oplemu" ) ); mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM"); @@ -751,10 +754,10 @@ Module::Module( Section* configuration ) : Module_base(configuration) { handler = new DBOPL::Handler(); } handler->Init( rate ); - Bit8u portRange = 4; //opl2 will set this to 2 + bool single = false; switch ( oplmode ) { case OPL_opl2: - portRange = 2; + single = true; Init( Adlib::MODE_OPL2 ); break; case OPL_dualopl2: @@ -765,14 +768,16 @@ Module::Module( Section* configuration ) : Module_base(configuration) { break; } //0x388 range - WriteHandler[0].Install(0x388,OPL_Write,IO_MB, portRange ); - ReadHandler[0].Install(0x388,OPL_Read,IO_MB, portRange - 1 ); + WriteHandler[0].Install(0x388,OPL_Write,IO_MB, 4 ); + ReadHandler[0].Install(0x388,OPL_Read,IO_MB, 4 ); //0x220 range - WriteHandler[1].Install(base,OPL_Write,IO_MB, portRange ); - ReadHandler[1].Install(base,OPL_Read,IO_MB, portRange - 1 ); + if ( !single ) { + WriteHandler[1].Install(base,OPL_Write,IO_MB, 4 ); + ReadHandler[1].Install(base,OPL_Read,IO_MB, 4 ); + } //0x228 range - WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2); - ReadHandler[2].Install(base+8,OPL_Read,IO_MB,1); + WriteHandler[2].Install(base+8,OPL_Write,IO_MB, 2); + ReadHandler[2].Install(base+8,OPL_Read,IO_MB, 1); MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL"); } diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index 7c65e04..4fb4f47 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -27,8 +27,7 @@ //TODO Don't delay first operator 1 sample in opl3 mode //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though? - //TODO don't use variables in work structure for tremolo and vibrato but give the variables as parameters to GetSample - //TODO Since the vibrato takes 1024 samples it's easier to run the emulator in same vibrato chunks, vibrato would be costfree + //TODO Check if having the same accuracy in all frequency multipliers sounds better or not //DUNNO Keyon in 4op, switch to 2op without keyoff. */ @@ -47,22 +46,31 @@ namespace DBOPL { -#define MAX_SAMPLES 256 #define OPLRATE ((double)(14318180.0 / 288.0)) - -//Only need 4 valid bits at the top for vibrato -#define VIBRATO_SH ( 32 - 4 ) -//Need 6 bits of accuracy -#define TREMOLO_SH ( 32 - 6 ) #define TREMOLO_TABLE 52 +//Try to use most precision for frequencies +//Else try to keep different waves in synch +//#define WAVE_PRECISION 1 +#ifndef WAVE_PRECISION //Wave bits available in the top of the 32bit range -//Original adlib uses 10.10, we use 12.20 -//Have to keep some bits in the top to allow for freqmul 0.5 -#define WAVE_BITS 12 +//Original adlib uses 10.10, we use 10.22 +#define WAVE_BITS 10 +#else +//Need some extra bits at the top to have room for octaves and frequency multiplier +//We support to 8 times lower rate +//128 * 15 * 8 = 15350, 2^13.9, so need 14 bits +#define WAVE_BITS 14 +#endif #define WAVE_SH ( 32 - WAVE_BITS ) #define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 ) +//Use the same accuracy as the waves +#define LFO_SH ( WAVE_SH - 10 ) +//LFO is controlled by our tremolo 256 sample limit +#define LFO_MAX ( 256 << ( LFO_SH ) ) + + //Maximum amount of attenuation bits //Envelope goes to 511, 9 bits #if (DBOPL_WAVE == WAVE_TABLEMUL ) @@ -271,21 +279,6 @@ static const WaveHandler WaveHandlerTable[8] = { #endif -//Structto hold the data everything well yeh works with -static struct { - Bitu samples; - Bits vibrato; - Bits tremolo; - inline void SetVibrato( Bit8s vib ) { - vibrato = vib; - vibrato &= ~0x80; - } - Bit32s output[MAX_SAMPLES * 2]; - //Could intermix the vib/trem table for slightly better cache hits - Bit8s vibTable[MAX_SAMPLES]; - Bit8s tremTable[MAX_SAMPLES]; -} Work; - /* Operator */ @@ -343,11 +336,20 @@ inline void Operator::UpdateAttenuation( ) { void Operator::UpdateFrequency( ) { Bit32u freq = chanData & (( 1 << 10 ) - 1); Bit32u block = (chanData >> 10) & 0xff; - - waveAdd = (freq << block) * freqMul; +#ifdef WAVE_PRECISION + block = 7 - block; + waveAdd = ( freq * freqMul ) >> block; +#else + waveAdd = ( freq << block ) * freqMul; +#endif if ( reg20 & MASK_VIBRATO ) { vibStrength = (Bit8u)(freq >> 7); + +#ifdef WAVE_PRECISION + vibrato = ( vibStrength * freqMul ) >> block; +#else vibrato = ( vibStrength << block ) * freqMul; +#endif } else { vibStrength = 0; vibrato = 0; @@ -378,7 +380,7 @@ INLINE Bit32s Operator::RateForward( Bit32u add ) { template< Operator::State yes> Bits Operator::TemplateVolume( ) { - Bit32s vol = activeLevel; + Bit32s vol = volume; Bit32s change; switch ( yes ) { case OFF: @@ -389,7 +391,7 @@ Bits Operator::TemplateVolume( ) { return vol; vol += ( (~vol) * change ) >> 3; if ( vol < ENV_MIN ) { - activeLevel = ENV_MIN; + volume = ENV_MIN; rateIndex = 0; SetState( DECAY ); return ENV_MIN; @@ -400,7 +402,7 @@ Bits Operator::TemplateVolume( ) { if ( vol >= sustainLevel ) { //Check if we didn't overshoot max attenuation, then just go off if ( vol >= ENV_MAX ) { - activeLevel = ENV_MAX; + volume = ENV_MAX; SetState( OFF ); return ENV_MAX; } @@ -417,13 +419,13 @@ Bits Operator::TemplateVolume( ) { case RELEASE: vol += RateForward( releaseAdd );; if ( vol >= ENV_MAX ) { - activeLevel = ENV_MAX; + volume = ENV_MAX; SetState( OFF ); return ENV_MAX; } break; } - activeLevel = vol; + volume = vol; return vol; } @@ -436,31 +438,15 @@ static const VolumeHandler VolumeHandlerTable[5] = { }; INLINE Bitu Operator::ForwardVolume() { - return totalLevel + (this->*volHandler)() -#if defined ( DBOPL_TREMOLO ) - + (Work.tremolo & tremoloMask) -#endif - ; + return currentLevel + (this->*volHandler)(); } INLINE Bitu Operator::ForwardWave() { -#if defined ( DBOPL_VIBRATO ) - if ( vibStrength >> (Bit8u)(Work.vibrato) ) { - Bit32s add = vibrato >> (Bit8u)(Work.vibrato); - //Sign extend over the shift value - Bit32s neg = Work.vibrato >> 16; - //Negate the add with -1 or 0 - add = ( add ^ neg ) - neg; - waveIndex += add + waveAdd; - return waveIndex >> WAVE_SH; - } -#endif - waveIndex += waveAdd; + waveIndex += waveCurrent; return waveIndex >> WAVE_SH; } - void Operator::Write20( const Chip* chip, Bit8u val ) { Bit8u change = (reg20 ^ val ); if ( !change ) @@ -539,12 +525,25 @@ INLINE void Operator::SetState( Bit8u s ) { } INLINE bool Operator::Silent() const { - if ( !ENV_SILENT( totalLevel + activeLevel ) ) + if ( !ENV_SILENT( totalLevel + volume ) ) return false; if ( !(rateZero & ( 1 << state ) ) ) return false; return true; -}; +} + +INLINE void Operator::Prepare( const Chip* chip ) { + currentLevel = totalLevel + (chip->tremoloValue & tremoloMask); + waveCurrent = waveAdd; + if ( vibStrength >> chip->vibratoShift ) { + Bit32s add = vibrato >> chip->vibratoShift; + //Sign extend over the shift value + Bit32s neg = chip->vibratoSign; + //Negate the add with -1 or 0 + add = ( add ^ neg ) - neg; + waveCurrent += add; + } +} void Operator::KeyOn( Bit8u mask ) { if ( !keyOn ) { @@ -590,7 +589,7 @@ Bits INLINE Operator::GetSample( Bits modulation ) { Bitu vol = ForwardVolume(); if ( ENV_SILENT( vol ) ) { //Simply forward the wave - waveIndex += waveAdd; + waveIndex += waveCurrent; return 0; } else { Bitu index = ForwardWave(); @@ -604,6 +603,7 @@ Operator::Operator() { freqMul = 0; waveIndex = 0; waveAdd = 0; + waveCurrent = 0; keyOn = 0; ksr = 0; reg20 = 0; @@ -614,8 +614,9 @@ Operator::Operator() { SetState( OFF ); rateZero = (1 << OFF); sustainLevel = ENV_MAX; - activeLevel = ENV_MAX; + currentLevel = ENV_MAX; totalLevel = ENV_MAX; + volume = ENV_MAX; } /* @@ -786,7 +787,7 @@ void Channel::ResetC0( const Chip* chip ) { }; template< bool opl3Mode> -void Channel::GeneratePercussion( Bit32s* output ) { +INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { Channel* chan = this; //BassDrum @@ -805,8 +806,8 @@ void Channel::GeneratePercussion( Bit32s* output ) { Operator* op2 = ( this + 1 )->Op(0); Operator* op4 = ( this + 2 )->Op(0); - //Precalculate stuff used by other oupts - Bit32u noiseBit = rand() & 0x2; + //Precalculate stuff used by other outputs + Bit32u noiseBit = (chip->ForwardNoise() & 0x1) << 1; Bit32u c2 = op2->ForwardWave(); //(bit 7 ^ bit 2) | bit 3 -> combined in bit 1 Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 ); @@ -832,7 +833,10 @@ void Channel::GeneratePercussion( Bit32s* output ) { sample += op3->GetWave( sdIndex, sdVol ); } //Tom-tom - sample += op4->GetSample( 0 ); + Bit32u ttVol = op4->ForwardVolume(); + if ( !ENV_SILENT( ttVol ) ) { + sample += op4->GetWave( c4, ttVol ); + } //Top-Cymbal Operator* op5 = ( this + 2 )->Op(1); Bit32u tcVol = op5->ForwardVolume(); @@ -850,7 +854,7 @@ void Channel::GeneratePercussion( Bit32s* output ) { } template -Channel* Channel::BlockTemplate( ) { +Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { switch( mode ) { case sm2AM: case sm3AM: @@ -891,16 +895,24 @@ Channel* Channel::BlockTemplate( ) { } break; } - for ( Bitu i = 0; i < Work.samples; i++ ) { - Work.vibrato = Work.vibTable[i]; - Work.tremolo = Work.tremTable[i]; - + //Init the operators with the the current vibrato and tremolo values + Op( 0 )->Prepare( chip ); + Op( 1 )->Prepare( chip ); + if ( mode > sm4Start ) { + Op( 2 )->Prepare( chip ); + Op( 3 )->Prepare( chip ); + } + if ( mode > sm6Start ) { + Op( 4 )->Prepare( chip ); + Op( 5 )->Prepare( chip ); + } + for ( Bitu i = 0; i < samples; i++ ) { //Early out for percussion handlers if ( mode == sm2Percussion ) { - GeneratePercussion( Work.output + i ); + GeneratePercussion( chip, output + i ); continue; //Prevent some unitialized value bitching } else if ( mode == sm3Percussion ) { - GeneratePercussion( Work.output + i * 2 ); + GeneratePercussion( chip, output + i * 2 ); continue; //Prevent some unitialized value bitching } @@ -936,7 +948,7 @@ Channel* Channel::BlockTemplate( ) { switch( mode ) { case sm2AM: case sm2FM: - Work.output[ i ] += sample; + output[ i ] += sample; break; case sm3AM: case sm3FM: @@ -944,8 +956,8 @@ Channel* Channel::BlockTemplate( ) { case sm3AMFM: case sm3FMAM: case sm3AMAM: - Work.output[ i * 2 + 0 ] += sample & maskLeft; - Work.output[ i * 2 + 1 ] += sample & maskRight; + output[ i * 2 + 0 ] += sample & maskLeft; + output[ i * 2 + 1 ] += sample & maskRight; break; } } @@ -979,31 +991,53 @@ Chip::Chip() { opl3Active = 0; } - -Bit8u Chip::ForwardTremolo( ) { - tremoloCounter += tremoloAdd; - if ( tremoloCounter >= (TREMOLO_TABLE << TREMOLO_SH) ) { - tremoloCounter -= TREMOLO_TABLE << TREMOLO_SH; +INLINE Bit32u Chip::ForwardNoise() { + noiseCounter += noiseAdd; + Bitu count = noiseCounter >> LFO_SH; + noiseCounter &= WAVE_MASK; + for ( ; count > 0; --count ) { + //Noise calculation from mame + noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) ); + noiseValue >>= 1; } - Bitu index = tremoloCounter >> TREMOLO_SH; - return TremoloTable[ index ] >> tremoloShift; + return noiseValue; } -Bit8s Chip::ForwardVibrato( ) { - vibratoCounter += vibratoAdd; - Bitu index = vibratoCounter >> VIBRATO_SH; - //Vibrato shift, basically makes the shift greater reducing the actual final value - return VibratoTable[index & 7] + vibratoShift; +INLINE Bit32u Chip::ForwardLFO( Bit32u samples ) { + //Current vibrato value, runs 4x slower than tremolo + vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7; + vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength; + tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength; + + //Check hom many samples there can be done before the value changes + Bit32u todo = LFO_MAX - lfoCounter; + Bit32u count = (todo + lfoAdd - 1) / lfoAdd; + if ( count > samples ) { + count = samples; + lfoCounter += count * lfoAdd; + } else { + lfoCounter += count * lfoAdd; + lfoCounter &= (LFO_MAX - 1); + //Maximum of 7 vibrato value * 4 + vibratoIndex = ( vibratoIndex + 1 ) & 31; + //Clip tremolo to the the table size + if ( tremoloIndex + 1 < TREMOLO_TABLE ) + ++tremoloIndex; + else + tremoloIndex = 0; + } + return count; } + void Chip::WriteBD( Bit8u val ) { Bit8u change = regBD ^ val; if ( !change ) return; regBD = val; //TODO could do this with shift and xor? - vibratoShift = (val & 0x40) ? 0x00 : 0x01; - tremoloShift = (val & 0x80) ? 0x00 : 0x02; + vibratoStrength = (val & 0x40) ? 0x00 : 0x01; + tremoloStrength = (val & 0x80) ? 0x00 : 0x02; if ( val & 0x20 ) { //Drum was just enabled, make sure channel 6 has the right synth if ( change & 0x20 ) { @@ -1150,53 +1184,69 @@ Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { return 0; } -void Chip::GenerateBlock2( Bitu samples ) { - Work.samples = samples; - for ( Bitu i = 0; i < Work.samples; i++ ) { - Work.vibTable[i] = ForwardVibrato(); - Work.tremTable[i] = ForwardTremolo(); - Work.output[i] = 0; - } - int count = 0; - for( Channel* ch = chan; ch < chan + 9; ) { - count++; - ch = (ch->*(ch->synthHandler))(); +void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { + while ( total > 0 ) { + Bit32u samples = ForwardLFO( total ); + for ( Bitu i = 0; i < samples; i++ ) { + output[i] = 0; + } + int count = 0; + for( Channel* ch = chan; ch < chan + 9; ) { + count++; + ch = (ch->*(ch->synthHandler))( this, samples, output ); + } + total -= samples; + output += samples; } } -void Chip::GenerateBlock3( Bitu samples ) { - Work.samples = samples; - for ( Bitu i = 0; i < Work.samples; i++ ) { - Work.vibTable[i] = ForwardVibrato(); - Work.tremTable[i] = ForwardTremolo(); - Work.output[i*2 + 0] = 0; - Work.output[i*2 + 1] = 0; - } - int count = 0; - for( Channel* ch = chan; ch < chan + 18; ) { - count++; - ch = (ch->*(ch->synthHandler))(); +void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { + while ( total > 0 ) { + Bit32u samples = ForwardLFO( total ); + for ( Bitu i = 0; i < samples; i++ ) { + output[i * 2 + 0 ] = 0; + output[i * 2 + 1 ] = 0; + } + int count = 0; + for( Channel* ch = chan; ch < chan + 18; ) { + count++; + ch = (ch->*(ch->synthHandler))( this, samples, output ); + } + total -= samples; + output += samples * 2; } } void Chip::Setup( Bit32u rate ) { - //Vibrato forwards every 1024 samples - vibratoAdd = (Bit32u)((double)rate * (double)( 1 << (VIBRATO_SH - 10) ) / OPLRATE); - vibratoCounter = 0; - //tremolo forwards every 64 samples - //We use a 52 entry table, real is 210, so repeat each sample an extra 4 times - tremoloAdd = (Bit32u)((double)rate * (double)( 1 << (TREMOLO_SH - 6 - 2) ) / OPLRATE); - tremoloCounter = 0; - //10 bits of frequency counter + double original = OPLRATE; +// double original = rate; + double scale = original / (double)rate; + + //Noise counter is run at the same precision as general waves + noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); + noiseCounter = 0; + noiseValue = 1; //Make sure it triggers the noise xor the first time + //The low frequency oscillation counter + //Every time his overflows vibrato and tremoloindex are increased + lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); + lfoCounter = 0; + vibratoIndex = 0; + tremoloIndex = 0; + //With higher octave this gets shifted up //-1 since the freqCreateTable = *2 - double scale = (OPLRATE * (double)( 1 << ( WAVE_SH - 10 - 1))) / rate; +#ifdef WAVE_PRECISION + double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10)); for ( int i = 0; i < 16; i++ ) { - //Use rounding with 0.5 - freqMul[i] = (Bit32u)( 0.5 + scale * FreqCreateTable[ i ] ); + freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] ); } +#else + Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10))); + for ( int i = 0; i < 16; i++ ) { + freqMul[i] = freqScale * FreqCreateTable[ i ]; + } +#endif - scale = OPLRATE / rate; //-3 since the real envelope takes 8 steps to reach the single value we supply for ( Bit8u i = 0; i < 76; i++ ) { Bit8u index, shift; @@ -1456,12 +1506,15 @@ void Handler::WriteReg( Bit32u addr, Bit8u val ) { } void Handler::Generate( MixerChannel* chan, Bitu samples ) { + Bit32s buffer[ 512 * 2 ]; + if ( samples > 512 ) + samples = 512; if ( !chip.opl3Active ) { - chip.GenerateBlock2( samples ); - chan->AddSamples_m32( samples, Work.output ); + chip.GenerateBlock2( samples, buffer ); + chan->AddSamples_m32( samples, buffer ); } else { - chip.GenerateBlock3( samples ); - chan->AddSamples_s32( samples, Work.output ); + chip.GenerateBlock3( samples, buffer ); + chan->AddSamples_s32( samples, buffer ); } } diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index cf19f5b..3249eac 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -28,10 +28,6 @@ //Select the type of wave generator routine #define DBOPL_WAVE WAVE_TABLEMUL -//Enable vibrato in the output -#define DBOPL_VIBRATO -//Enable tremolo in the output -#define DBOPL_TREMOLO namespace DBOPL { @@ -44,20 +40,21 @@ typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); #endif typedef Bits ( DBOPL::Operator::*VolumeHandler) ( ); -typedef Channel* ( DBOPL::Channel::*SynthHandler) ( ); +typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output ); //Different synth modes that can generate blocks of data typedef enum { - smNone, sm2AM, sm2FM, - sm2Percussion, sm3AM, sm3FM, + sm4Start, sm3FMFM, sm3AMFM, sm3FMAM, sm3AMAM, + sm6Start, + sm2Percussion, sm3Percussion, } SynthMode; @@ -95,14 +92,16 @@ public: Bit32u waveStart; #endif Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index - Bit32u waveAdd; + Bit32u waveAdd; //The base frequency without vibrato + Bit32u waveCurrent; //waveAdd + vibratao Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? Bit32u vibrato; //Scaled up vibrato strength Bit32s sustainLevel; //When stopping at sustain level stop here - Bit32s totalLevel; //totalLeve is added to every generated volume - Bit32s activeLevel; //The currently active volume + Bit32s totalLevel; //totalLevel is added to every generated volume + Bit32u currentLevel; //totalLevel + tremolo + Bit32s volume; //The currently active volume Bit32u attackAdd; //Timers for the different states of the envelope Bit32u decayAdd; @@ -129,7 +128,7 @@ private: public: void UpdateAttenuation(); void UpdateRates( const Chip* chip ); - void UpdateFrequency( ); + void UpdateFrequency( ); void Write20( const Chip* chip, Bit8u val ); void Write40( const Chip* chip, Bit8u val ); @@ -138,6 +137,8 @@ public: void WriteE0( const Chip* chip, Bit8u val ); bool Silent() const; + void Prepare( const Chip* chip ); + void KeyOn( Bit8u mask); void KeyOff( Bit8u mask); @@ -182,20 +183,23 @@ struct Channel { //call this for the first channel template< bool opl3Mode > - void GeneratePercussion( Bit32s* output ); + void GeneratePercussion( Chip* chip, Bit32s* output ); //Generate blocks of data in specific modes template - Channel* BlockTemplate( ); + Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ); Channel(); }; struct Chip { //This is used as the base counter for vibrato and tremolo - Bit32u tremoloCounter; - Bit32u tremoloAdd; - Bit32u vibratoCounter; - Bit32u vibratoAdd; + Bit32u lfoCounter; + Bit32u lfoAdd; + + + Bit32u noiseCounter; + Bit32u noiseAdd; + Bit32u noiseValue; //Frequency scales for the different multiplications Bit32u freqMul[16]; @@ -211,23 +215,29 @@ struct Chip { Bit8u reg08; Bit8u reg04; Bit8u regBD; + Bit8u vibratoIndex; + Bit8u tremoloIndex; + Bit8s vibratoSign; Bit8u vibratoShift; - Bit8u tremoloShift; + Bit8u tremoloValue; + Bit8u vibratoStrength; + Bit8u tremoloStrength; //Mask for allowed wave forms Bit8u waveFormMask; //0 or -1 when enabled Bit8s opl3Active; - Bit8u ForwardTremolo(); - Bit8s ForwardVibrato(); + //Return the maximum amount of samples before and LFO change + Bit32u ForwardLFO( Bit32u samples ); + Bit32u ForwardNoise(); void WriteBD( Bit8u val ); void WriteReg(Bit32u reg, Bit8u val ); Bit32u WriteAddr( Bit32u port, Bit8u val ); - void GenerateBlock2( Bitu samples ); - void GenerateBlock3( Bitu samples ); + void GenerateBlock2( Bitu samples, Bit32s* output ); + void GenerateBlock3( Bitu samples, Bit32s* output ); void Generate( Bit32u samples ); void Setup( Bit32u r ); diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index fa45813..d22757b 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * Copyright (C) 2002-2009 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: disney.cpp,v 1.16 2008/07/14 19:39:10 qbix79 Exp $ */ +/* $Id: disney.cpp,v 1.17 2009/05/14 17:04:37 qbix79 Exp $ */ #include #include "dosbox.h" @@ -56,6 +56,7 @@ static struct { Bitu state; Bitu interface_det; + Bitu interface_det_ext; } disney; #define DS_IDLE 0 @@ -71,12 +72,13 @@ static void DISNEY_disable(Bitu) { disney.chan->Enable(false); delete disney.mo; } - disney.interface_det = 0; disney.leader = 0; disney.last_used = 0; disney.mo = 0; disney.state = DS_IDLE; disney.interface_det = 0; + disney.interface_det_ext = 0; + disney.stereo = false; } static void DISNEY_enable(Bitu freq) { @@ -197,7 +199,6 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { disney.da[0].buffer[disney.da[0].used] = disney.data; disney.da[0].used++; } //else LOG_MSG("disney overflow 0"); - } break; } @@ -208,6 +209,7 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { if((disney.control & 0x2) && !(val & 0x2)) { if(disney.state != DS_RUNNING) { disney.interface_det = 0; + disney.interface_det_ext = 0; DISNEY_analyze(1); } @@ -221,6 +223,7 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { if((disney.control & 0x1) && !(val & 0x1)) { if(disney.state != DS_RUNNING) { disney.interface_det = 0; + disney.interface_det_ext = 0; DISNEY_analyze(0); } // stereo channel latch @@ -230,6 +233,24 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { } //else LOG_MSG("disney overflow 0"); } + if((disney.control & 0x8) && !(val & 0x8)) { + // emulate a device with 16-byte sound FIFO + if(disney.state != DS_RUNNING) { + disney.interface_det_ext++; + disney.interface_det = 0; + if(disney.interface_det_ext > 5) { + disney.leader = &disney.da[0]; + DISNEY_enable(7000); + } + } + if(disney.interface_det_ext > 5) { + if(disney.da[0].used < DISNEY_SIZE) { + disney.da[0].buffer[disney.da[0].used] = disney.data; + disney.da[0].used++; + } + } + } + // LOG_WARN("DISNEY:Control write %x",val); if (val&0x10) LOG(LOG_MISC,LOG_ERROR)("DISNEY:Parallel IRQ Enabled"); disney.control=val; @@ -238,6 +259,7 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) { } static Bitu disney_read(Bitu port,Bitu iolen) { + Bitu retval; switch (port-DISNEY_BASE) { case 0: /* Data Port */ // LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from data port"); @@ -245,10 +267,15 @@ static Bitu disney_read(Bitu port,Bitu iolen) { break; case 1: /* Status Port */ // LOG(LOG_MISC,"DISNEY:Read from status port %X",disney.status); - if (disney.leader && disney.leader->used >= 16) return 0x40; - /* Stereo-on-1 and (or) New-Stereo DACs present */ - if(!(disney.data&0x80)) return 0xc4; - else return 0x0; + retval = 0x07;//0x40; // Stereo-on-1 and (or) New-Stereo DACs present + if(disney.interface_det_ext > 5) { + if (disney.leader && disney.leader->used >= 16){ + retval |= 0x40; // ack + retval &= ~0x4; // interrupt + } + } + if(!(disney.data&0x80)) retval |= 0x80; // pin 9 is wired to pin 11 + return retval; break; case 2: /* Control Port */ LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from control port"); diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index c8ede58..9587519 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -64,7 +64,6 @@ Revision History: //#include "driver.h" /* use M.A.M.E. */ #include "fmopl.h" -#include "config.h" // INLINE #ifndef PI #define PI 3.14159265358979323846 diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index d779785..29dbb5d 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.15 2008/07/26 14:49:38 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.16 2009/05/15 18:16:33 qbix79 Exp $ */ #include "dosbox.h" @@ -951,7 +951,8 @@ public: isIpxServer = true; ConnectToServer("localhost"); } else { - WriteOut("IPX Tunneling Server failed to start\n"); + WriteOut("IPX Tunneling Server failed to start.\n"); + if(udpPort < 1024) WriteOut("Try a port number above 1024. See IPXNET HELP CONNECT on how to specify a port.\n"); } } else { WriteOut("IPX Tunneling Server already started\n"); diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 5e8476d..9693a30 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -18,7 +18,7 @@ /* $Id: mixer.cpp,v 1.53 2009/04/28 21:48:24 harekiet Exp $ */ -/* +/* Remove the sdl code from here and have it handeld in the sdlmain. That should call the mixer start from there or something. */ @@ -265,7 +265,7 @@ thestart: void MixerChannel::AddStretched(Bitu len,Bit16s * data) { if (done>=needed) { - LOG_MSG("Can't add, buffer full"); + LOG_MSG("Can't add, buffer full"); return; } Bitu outlen=needed-done;Bits diff; @@ -353,7 +353,7 @@ void MixerChannel::FillUp(void) { extern bool ticksLocked; static inline bool Mixer_irq_important(void) { - /* In some states correct timing of the irqs is more important then + /* In some states correct timing of the irqs is more important then * non stuttering audo */ return (ticksLocked || (CaptureState & (CAPTURE_WAVE|CAPTURE_VIDEO))); } @@ -368,7 +368,7 @@ static void MIXER_MixData(Bitu needed) { if (CaptureState & (CAPTURE_WAVE|CAPTURE_VIDEO)) { Bit16s convert[1024][2]; Bitu added=needed-mixer.done; - if (added>1024) + if (added>1024) added=1024; Bitu readpos=(mixer.pos+mixer.done)&MIXER_BUFMASK; for (Bitu i=0;i MIXER_BUFSIZE) index_add = MIXER_BUFSIZE - 2*mixer.min_needed; - else + else index_add = mixer.done - 2*mixer.min_needed; index_add = (index_add << MIXER_SHIFT) / need; reduce = mixer.done - 2* mixer.min_needed; @@ -480,7 +480,7 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { if (chan->done>reduce) chan->done-=reduce; else chan->done=0; } - + // Reset mixer.tick_add when irqs are important if( Mixer_irq_important() ) mixer.tick_add=(mixer.freq<< MIXER_SHIFT)/1000; @@ -570,7 +570,7 @@ public: chan=mixer.channels; WriteOut("Channel Main Main(dB)\n"); ShowVolume("MASTER",mixer.mastervol[0],mixer.mastervol[1]); - for (chan=mixer.channels;chan;chan=chan->next) + for (chan=mixer.channels;chan;chan=chan->next) ShowVolume(chan->name,chan->volmain[0],chan->volmain[1]); } private: @@ -583,7 +583,7 @@ private: void ListMidi(){ #if defined (WIN32) - unsigned int total = midiOutGetNumDevs(); + unsigned int total = midiOutGetNumDevs(); for(unsigned int i=0;iamp = 1.0; op_pt->step_amp = 1.0; } - op_pt->step_skip_pos <<= 1; - if (op_pt->step_skip_pos==0) op_pt->step_skip_pos = 1; - if (op_pt->step_skip_pos & op_pt->env_step_skip_a) { // check if required to skip next step + op_pt->step_skip_pos_a <<= 1; + if (op_pt->step_skip_pos_a==0) op_pt->step_skip_pos_a = 1; + if (op_pt->step_skip_pos_a & op_pt->env_step_skip_a) { // check if required to skip next step op_pt->step_amp = op_pt->amp; } } @@ -494,7 +504,7 @@ void adlib_init(Bit32u samplerate) { op[i].env_step_a = 0; op[i].env_step_d = 0; op[i].env_step_r = 0; - op[i].step_skip_pos = 0; + op[i].step_skip_pos_a = 0; op[i].env_step_skip_a = 0; #if defined(OPLTYPE_IS_OPL3) @@ -559,9 +569,9 @@ void adlib_init(Bit32u samplerate) { wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1) )*PI*2/WAVEPREC)); wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC)); wavtable[i] = wavtable[(i<<1) +WAVEPREC]; - // table to be verified, alternative: (zero-less) -/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1)-1)*PI/WAVEPREC)); - wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1) )*PI/WAVEPREC)); + // alternative: (zero-less) +/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+1)*PI/WAVEPREC)); + wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+3)*PI/WAVEPREC)); wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */ } for (i=0;i<(WAVEPREC>>3);i++) { @@ -589,7 +599,6 @@ void adlib_init(Bit32u samplerate) { void adlib_write(Bitu idx, Bit8u val) { Bit32u second_set = idx&0x100; - Bit8u old_val = adlibreg[idx]; adlibreg[idx] = val; switch (idx&0xf0) { @@ -910,7 +919,7 @@ void adlib_write_index(Bitu port, Bit8u val) { #endif } -static void INLINE clipit16(Bit32s ival, Bit16s* outval) { +static void OPL_INLINE clipit16(Bit32s ival, Bit16s* outval) { if (ival<32768) { if (ival>-32769) { *outval=(Bit16s)ival; diff --git a/src/hardware/opl.h b/src/hardware/opl.h index 3cbcbab..3aa431c 100644 --- a/src/hardware/opl.h +++ b/src/hardware/opl.h @@ -42,6 +42,13 @@ typedef uint8_t Bit8u; typedef int8_t Bit8s; */ + +/* + define attribution that inlines/forces inlining of a function (optional) +*/ +#define OPL_INLINE INLINE + + #undef NUM_CHANNELS #if defined(OPLTYPE_IS_OPL3) #define NUM_CHANNELS 18 @@ -135,7 +142,7 @@ typedef struct operator_struct { Bit32u generator_pos; // for non-standard sample rates we need to determine how many samples have passed Bits cur_env_step; // current (standardized) sample position Bits env_step_a,env_step_d,env_step_r; // number of std samples of one step (for attack/decay/release mode) - Bit8u step_skip_pos; // position of 8-cyclic step skipping (always 2^x to check against mask) + Bit8u step_skip_pos_a; // position of 8-cyclic step skipping (always 2^x to check against mask) Bits env_step_skip_a; // bitmask that determines if a step is skipped (respective bit is zero then) #if defined(OPLTYPE_IS_OPL3) diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index f756ad7..ec1526b 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.24 2007/07/15 16:36:27 c2woody Exp $ */ + /* $Id: pcspeaker.cpp,v 1.25 2009/05/14 18:51:53 qbix79 Exp $ */ #include #include "dosbox.h" @@ -305,15 +305,21 @@ static void PCSPEAKER_CallBack(Bitu len) { if(spkr.chan) spkr.chan->AddSamples_m16(len,(Bit16s*)MixTemp); //Turn off speaker after 10 seconds of idle or one second idle when in off mode + bool turnoff = false; Bitu test_ticks = PIC_Ticks; - if ((spkr.last_ticks+10000)Enable(false); + if ((spkr.last_ticks + 10000) < test_ticks) turnoff = true; + if((spkr.mode == SPKR_OFF) && ((spkr.last_ticks + 1000) < test_ticks)) turnoff = true; + + if(turnoff){ + if(spkr.volwant == 0) { + spkr.last_ticks = 0; + if(spkr.chan) spkr.chan->Enable(false); + } else { + if(spkr.volwant > 0) spkr.volwant--; else spkr.volwant++; + + } } - if((spkr.mode == SPKR_OFF) && ((spkr.last_ticks+1000) Enable(false); - } + } class PCSPEAKER:public Module_base { private: diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 49cd2a6..90d69a5 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -50,16 +50,19 @@ Note: Each read or write of this register will cycle through first the enum {DAC_READ,DAC_WRITE}; -static INLINE void VGA_DAC_UpdateColor( Bitu index ) { +static void VGA_DAC_SendColor( Bitu index, Bitu src ) { + const Bit8u red = vga.dac.rgb[src].red; + const Bit8u green = vga.dac.rgb[src].green; + const Bit8u blue = vga.dac.rgb[src].blue; + //Set entry in 16bit output lookup table + vga.dac.xlat16[index] = ((blue>>1)&0x1f) | (((green)&0x3f)<<5) | (((red>>1)&0x1f) << 11); + + RENDER_SetPal( index, (red << 2) | ( red >> 4 ), (green << 2) | ( green >> 4 ), (blue << 2) | ( blue >> 4 ) ); +} + +static void VGA_DAC_UpdateColor( Bitu index ) { Bitu maskIndex = index & vga.dac.pel_mask; - vga.dac.xlat16[index] = ((vga.dac.rgb[maskIndex].blue>>1)&0x1f) | - (((vga.dac.rgb[maskIndex].green)&0x3f)<<5)| - (((vga.dac.rgb[maskIndex].red>>1)&0x1f) << 11); - RENDER_SetPal( index, - vga.dac.rgb[maskIndex].red << 2, - vga.dac.rgb[maskIndex].green << 2, - vga.dac.rgb[maskIndex].blue << 2 - ); + VGA_DAC_SendColor( index, maskIndex ); } static void write_p3c6(Bitu port,Bitu val,Bitu iolen) { @@ -129,14 +132,7 @@ static void write_p3c9(Bitu port,Bitu val,Bitu iolen) { /* Check for attributes and DAC entry link */ for (Bitu i=0;i<16;i++) { if (vga.dac.combine[i]==vga.dac.write_index) { - vga.dac.xlat16[i] = ( - (vga.dac.rgb[vga.dac.write_index].blue>>1)&0x1f) | - (((vga.dac.rgb[vga.dac.write_index].green)&0x3f)<<5)| - (((vga.dac.rgb[vga.dac.write_index].red>>1)&0x1f) << 11); - RENDER_SetPal(i, - vga.dac.rgb[vga.dac.write_index].red << 2, - vga.dac.rgb[vga.dac.write_index].green << 2, - vga.dac.rgb[vga.dac.write_index].blue << 2); + VGA_DAC_SendColor( i, vga.dac.write_index ); } } } @@ -184,16 +180,8 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { case M_VGA: // used by copper demo; almost no video card seems to suport it if(!IS_VGA_ARCH || (svgaCard!=SVGA_None)) break; - default: - vga.dac.xlat16[attr] = ((vga.dac.rgb[pal].blue>>1)&0x1f) | - (((vga.dac.rgb[pal].green)&0x3f)<<5)| - (((vga.dac.rgb[pal].red>>1)&0x1f) << 11); - RENDER_SetPal(attr, - vga.dac.rgb[pal].red << 2, - vga.dac.rgb[pal].green << 2, - vga.dac.rgb[pal].blue << 2 - ); + VGA_DAC_SendColor( attr, pal ); } } @@ -204,7 +192,7 @@ void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) { vga.dac.rgb[entry].blue=blue; for (Bitu i=0;i<16;i++) if (vga.dac.combine[i]==entry) - RENDER_SetPal(i,red << 2,green << 2,blue << 2); + VGA_DAC_SendColor( i, i ); } void VGA_SetupDAC(void) { diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 345b278..87650a8 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2008 The DOSBox Team + * Copyright (C) 2002-2009 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: ems.cpp,v 1.60 2008/11/27 18:57:45 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.62 2009/05/14 17:51:47 qbix79 Exp $ */ #include #include @@ -79,16 +79,16 @@ public: SetName("EMMXXXX0"); GEMMIS_seg=0; } - bool Read(Bit8u * data,Bit16u * size) { return false;} - bool Write(Bit8u * data,Bit16u * size){ + bool Read(Bit8u * /*data*/,Bit16u * /*size*/) { return false;} + bool Write(Bit8u * /*data*/,Bit16u * /*size*/){ LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device"); return false; } - bool Seek(Bit32u * pos,Bit32u type){return false;} + bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;} bool Close(){return false;} Bit16u GetInformation(void){return 0xc080;} bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); - bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} + bool WriteToControlChannel(PhysPt /*bufptr*/,Bit16u /*size*/,Bit16u * /*retcode*/){return true;} private: Bit8u cache; }; @@ -126,7 +126,7 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco mem_writeb(GEMMIS_addr+0x0a+frnr,0x03); // frame type: EMS frame in 64k page mem_writeb(GEMMIS_addr+0x0b+frnr,0xff); // owner: NONE mem_writew(GEMMIS_addr+0x0c+frnr,0x7fff); // no logical page number - mem_writeb(GEMMIS_addr+0x0e + frnr,frct); // physical EMS page number + mem_writeb(GEMMIS_addr+0x0e + frnr,(Bit8u)(frct&0xff)); // physical EMS page number mem_writeb(GEMMIS_addr+0x0f+frnr,0x00); // EMS frame } /* build non-EMS ROM frames (0xf000-0x10000) */ @@ -224,8 +224,11 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle,bool can_allocate_ while (emm_handles[handle].pages != NULL_HANDLE) { if (++handle >= EMM_MAX_HANDLES) {return EMM_OUT_OF_HANDLES;} } - MemHandle mem = MEM_AllocatePages(pages*4,false); - if (!mem) E_Exit("EMS:Memory allocation failure"); + MemHandle mem = 0; + if (pages) { + mem = MEM_AllocatePages(pages*4,false); + if (!mem) E_Exit("EMS:Memory allocation failure"); + } emm_handles[handle].pages = pages; emm_handles[handle].mem = mem; /* Change handle only if there is no error. */ @@ -251,8 +254,14 @@ static Bit8u EMM_AllocateSystemHandle(Bit16u pages) { static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) { /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; - /* Check for enough pages */ - if (!MEM_ReAllocatePages(emm_handles[handle].mem,pages*4,false)) return EMM_OUT_OF_LOG; + if (emm_handles[handle].pages != 0) { + /* Check for enough pages */ + if (!MEM_ReAllocatePages(emm_handles[handle].mem,pages*4,false)) return EMM_OUT_OF_LOG; + } else { + MemHandle mem = MEM_AllocatePages(pages*4,false); + if (!mem) E_Exit("EMS:Memory allocation failure during reallocation"); + emm_handles[handle].mem = mem; + } /* Update size */ emm_handles[handle].pages=pages; return EMM_NO_ERROR; @@ -347,9 +356,14 @@ static Bit8u EMM_MapSegment(Bitu segment,Bit16u handle,Bit16u log_page) { static Bit8u EMM_ReleaseMemory(Bit16u handle) { /* Check for valid handle */ if (!ValidHandle(handle)) return EMM_INVALID_HANDLE; + // should check for saved_page_map flag here, returning an error if it's true // as apps are required to restore the pagemap beforehand; to be checked - MEM_ReleasePages(emm_handles[handle].mem); +// if (emm_handles[handle].saved_page_map) return EMM_SAVEMAP_ERROR; + + if (emm_handles[handle].pages != 0) { + MEM_ReleasePages(emm_handles[handle].mem); + } /* Reset handle */ emm_handles[handle].mem=0; if (handle==0) { @@ -1370,7 +1384,7 @@ public: static EMS* test; -void EMS_ShutDown(Section* sec) { +void EMS_ShutDown(Section* /*sec*/) { delete test; } diff --git a/src/libs/gui_tk/gui_tk.h b/src/libs/gui_tk/gui_tk.h index 16674f6..696c89f 100644 --- a/src/libs/gui_tk/gui_tk.h +++ b/src/libs/gui_tk/gui_tk.h @@ -102,13 +102,13 @@ * along with this program. If not, see */ -/* $Id: gui_tk.h,v 1.5 2008/09/07 10:55:15 c2woody Exp $ */ +/* $Id: gui_tk.h,v 1.6 2009/05/17 15:28:05 c2woody Exp $ */ #ifndef GUI__TOOLKIT_H #define GUI__TOOLKIT_H -#define imin(x,y) (xy?x:y) +#define imin(x,y) ((x)<(y)?(x):(y)) +#define imax(x,y) ((x)>(y)?(x):(y)) #define isign(x) (((x)<0?-1:1)) /** \file @@ -1263,7 +1263,7 @@ public: const SpecialChar *special = NULL); virtual ~BitmapFont(); - + /// Retrieve total height of font in pixels. virtual int getHeight() const { return height; };