mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-11-17 15:49:15 +01:00
sync to dosbox svn
This commit is contained in:
parent
e09f1acccf
commit
022766bc73
@ -16,7 +16,7 @@
|
|||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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 <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -530,8 +530,8 @@ void Module::DualWrite( Bit8u index, Bit8u reg, Bit8u val ) {
|
|||||||
if ( chip[index].Write( reg, val ) )
|
if ( chip[index].Write( reg, val ) )
|
||||||
return;
|
return;
|
||||||
//Enabling panning
|
//Enabling panning
|
||||||
if ( reg >= 0xc0 && reg <0xc8 ) {
|
if ( reg >= 0xc0 && reg <=0xc8 ) {
|
||||||
val &= 7;
|
val &= 0x0f;
|
||||||
val |= index ? 0xA0 : 0x50;
|
val |= index ? 0xA0 : 0x50;
|
||||||
}
|
}
|
||||||
Bit32u fullReg = reg + (index ? 0x100 : 0);
|
Bit32u fullReg = reg + (index ? 0x100 : 0);
|
||||||
@ -729,6 +729,9 @@ Module::Module( Section* configuration ) : Module_base(configuration) {
|
|||||||
Section_prop * section=static_cast<Section_prop *>(configuration);
|
Section_prop * section=static_cast<Section_prop *>(configuration);
|
||||||
Bitu base = section->Get_hex("sbbase");
|
Bitu base = section->Get_hex("sbbase");
|
||||||
Bitu rate = section->Get_int("oplrate");
|
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" ) );
|
std::string oplemu( section->Get_string( "oplemu" ) );
|
||||||
|
|
||||||
mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM");
|
mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM");
|
||||||
@ -751,10 +754,10 @@ Module::Module( Section* configuration ) : Module_base(configuration) {
|
|||||||
handler = new DBOPL::Handler();
|
handler = new DBOPL::Handler();
|
||||||
}
|
}
|
||||||
handler->Init( rate );
|
handler->Init( rate );
|
||||||
Bit8u portRange = 4; //opl2 will set this to 2
|
bool single = false;
|
||||||
switch ( oplmode ) {
|
switch ( oplmode ) {
|
||||||
case OPL_opl2:
|
case OPL_opl2:
|
||||||
portRange = 2;
|
single = true;
|
||||||
Init( Adlib::MODE_OPL2 );
|
Init( Adlib::MODE_OPL2 );
|
||||||
break;
|
break;
|
||||||
case OPL_dualopl2:
|
case OPL_dualopl2:
|
||||||
@ -765,14 +768,16 @@ Module::Module( Section* configuration ) : Module_base(configuration) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//0x388 range
|
//0x388 range
|
||||||
WriteHandler[0].Install(0x388,OPL_Write,IO_MB, portRange );
|
WriteHandler[0].Install(0x388,OPL_Write,IO_MB, 4 );
|
||||||
ReadHandler[0].Install(0x388,OPL_Read,IO_MB, portRange - 1 );
|
ReadHandler[0].Install(0x388,OPL_Read,IO_MB, 4 );
|
||||||
//0x220 range
|
//0x220 range
|
||||||
WriteHandler[1].Install(base,OPL_Write,IO_MB, portRange );
|
if ( !single ) {
|
||||||
ReadHandler[1].Install(base,OPL_Read,IO_MB, portRange - 1 );
|
WriteHandler[1].Install(base,OPL_Write,IO_MB, 4 );
|
||||||
|
ReadHandler[1].Install(base,OPL_Read,IO_MB, 4 );
|
||||||
|
}
|
||||||
//0x228 range
|
//0x228 range
|
||||||
WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2);
|
WriteHandler[2].Install(base+8,OPL_Write,IO_MB, 2);
|
||||||
ReadHandler[2].Install(base+8,OPL_Read,IO_MB,1);
|
ReadHandler[2].Install(base+8,OPL_Read,IO_MB, 1);
|
||||||
|
|
||||||
MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL");
|
MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL");
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,7 @@
|
|||||||
//TODO Don't delay first operator 1 sample in opl3 mode
|
//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 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 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 Check if having the same accuracy in all frequency multipliers sounds better or not
|
||||||
//TODO Since the vibrato takes 1024 samples it's easier to run the emulator in same vibrato chunks, vibrato would be costfree
|
|
||||||
|
|
||||||
//DUNNO Keyon in 4op, switch to 2op without keyoff.
|
//DUNNO Keyon in 4op, switch to 2op without keyoff.
|
||||||
*/
|
*/
|
||||||
@ -47,22 +46,31 @@
|
|||||||
|
|
||||||
namespace DBOPL {
|
namespace DBOPL {
|
||||||
|
|
||||||
#define MAX_SAMPLES 256
|
|
||||||
#define OPLRATE ((double)(14318180.0 / 288.0))
|
#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
|
#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
|
//Wave bits available in the top of the 32bit range
|
||||||
//Original adlib uses 10.10, we use 12.20
|
//Original adlib uses 10.10, we use 10.22
|
||||||
//Have to keep some bits in the top to allow for freqmul 0.5
|
#define WAVE_BITS 10
|
||||||
#define WAVE_BITS 12
|
#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_SH ( 32 - WAVE_BITS )
|
||||||
#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 )
|
#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
|
//Maximum amount of attenuation bits
|
||||||
//Envelope goes to 511, 9 bits
|
//Envelope goes to 511, 9 bits
|
||||||
#if (DBOPL_WAVE == WAVE_TABLEMUL )
|
#if (DBOPL_WAVE == WAVE_TABLEMUL )
|
||||||
@ -271,21 +279,6 @@ static const WaveHandler WaveHandlerTable[8] = {
|
|||||||
|
|
||||||
#endif
|
#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
|
Operator
|
||||||
*/
|
*/
|
||||||
@ -343,11 +336,20 @@ inline void Operator::UpdateAttenuation( ) {
|
|||||||
void Operator::UpdateFrequency( ) {
|
void Operator::UpdateFrequency( ) {
|
||||||
Bit32u freq = chanData & (( 1 << 10 ) - 1);
|
Bit32u freq = chanData & (( 1 << 10 ) - 1);
|
||||||
Bit32u block = (chanData >> 10) & 0xff;
|
Bit32u block = (chanData >> 10) & 0xff;
|
||||||
|
#ifdef WAVE_PRECISION
|
||||||
waveAdd = (freq << block) * freqMul;
|
block = 7 - block;
|
||||||
|
waveAdd = ( freq * freqMul ) >> block;
|
||||||
|
#else
|
||||||
|
waveAdd = ( freq << block ) * freqMul;
|
||||||
|
#endif
|
||||||
if ( reg20 & MASK_VIBRATO ) {
|
if ( reg20 & MASK_VIBRATO ) {
|
||||||
vibStrength = (Bit8u)(freq >> 7);
|
vibStrength = (Bit8u)(freq >> 7);
|
||||||
|
|
||||||
|
#ifdef WAVE_PRECISION
|
||||||
|
vibrato = ( vibStrength * freqMul ) >> block;
|
||||||
|
#else
|
||||||
vibrato = ( vibStrength << block ) * freqMul;
|
vibrato = ( vibStrength << block ) * freqMul;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
vibStrength = 0;
|
vibStrength = 0;
|
||||||
vibrato = 0;
|
vibrato = 0;
|
||||||
@ -378,7 +380,7 @@ INLINE Bit32s Operator::RateForward( Bit32u add ) {
|
|||||||
|
|
||||||
template< Operator::State yes>
|
template< Operator::State yes>
|
||||||
Bits Operator::TemplateVolume( ) {
|
Bits Operator::TemplateVolume( ) {
|
||||||
Bit32s vol = activeLevel;
|
Bit32s vol = volume;
|
||||||
Bit32s change;
|
Bit32s change;
|
||||||
switch ( yes ) {
|
switch ( yes ) {
|
||||||
case OFF:
|
case OFF:
|
||||||
@ -389,7 +391,7 @@ Bits Operator::TemplateVolume( ) {
|
|||||||
return vol;
|
return vol;
|
||||||
vol += ( (~vol) * change ) >> 3;
|
vol += ( (~vol) * change ) >> 3;
|
||||||
if ( vol < ENV_MIN ) {
|
if ( vol < ENV_MIN ) {
|
||||||
activeLevel = ENV_MIN;
|
volume = ENV_MIN;
|
||||||
rateIndex = 0;
|
rateIndex = 0;
|
||||||
SetState( DECAY );
|
SetState( DECAY );
|
||||||
return ENV_MIN;
|
return ENV_MIN;
|
||||||
@ -400,7 +402,7 @@ Bits Operator::TemplateVolume( ) {
|
|||||||
if ( vol >= sustainLevel ) {
|
if ( vol >= sustainLevel ) {
|
||||||
//Check if we didn't overshoot max attenuation, then just go off
|
//Check if we didn't overshoot max attenuation, then just go off
|
||||||
if ( vol >= ENV_MAX ) {
|
if ( vol >= ENV_MAX ) {
|
||||||
activeLevel = ENV_MAX;
|
volume = ENV_MAX;
|
||||||
SetState( OFF );
|
SetState( OFF );
|
||||||
return ENV_MAX;
|
return ENV_MAX;
|
||||||
}
|
}
|
||||||
@ -417,13 +419,13 @@ Bits Operator::TemplateVolume( ) {
|
|||||||
case RELEASE:
|
case RELEASE:
|
||||||
vol += RateForward( releaseAdd );;
|
vol += RateForward( releaseAdd );;
|
||||||
if ( vol >= ENV_MAX ) {
|
if ( vol >= ENV_MAX ) {
|
||||||
activeLevel = ENV_MAX;
|
volume = ENV_MAX;
|
||||||
SetState( OFF );
|
SetState( OFF );
|
||||||
return ENV_MAX;
|
return ENV_MAX;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
activeLevel = vol;
|
volume = vol;
|
||||||
return vol;
|
return vol;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,31 +438,15 @@ static const VolumeHandler VolumeHandlerTable[5] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
INLINE Bitu Operator::ForwardVolume() {
|
INLINE Bitu Operator::ForwardVolume() {
|
||||||
return totalLevel + (this->*volHandler)()
|
return currentLevel + (this->*volHandler)();
|
||||||
#if defined ( DBOPL_TREMOLO )
|
|
||||||
+ (Work.tremolo & tremoloMask)
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
INLINE Bitu Operator::ForwardWave() {
|
INLINE Bitu Operator::ForwardWave() {
|
||||||
#if defined ( DBOPL_VIBRATO )
|
waveIndex += waveCurrent;
|
||||||
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;
|
|
||||||
return waveIndex >> WAVE_SH;
|
return waveIndex >> WAVE_SH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Operator::Write20( const Chip* chip, Bit8u val ) {
|
void Operator::Write20( const Chip* chip, Bit8u val ) {
|
||||||
Bit8u change = (reg20 ^ val );
|
Bit8u change = (reg20 ^ val );
|
||||||
if ( !change )
|
if ( !change )
|
||||||
@ -539,12 +525,25 @@ INLINE void Operator::SetState( Bit8u s ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
INLINE bool Operator::Silent() const {
|
INLINE bool Operator::Silent() const {
|
||||||
if ( !ENV_SILENT( totalLevel + activeLevel ) )
|
if ( !ENV_SILENT( totalLevel + volume ) )
|
||||||
return false;
|
return false;
|
||||||
if ( !(rateZero & ( 1 << state ) ) )
|
if ( !(rateZero & ( 1 << state ) ) )
|
||||||
return false;
|
return false;
|
||||||
return true;
|
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 ) {
|
void Operator::KeyOn( Bit8u mask ) {
|
||||||
if ( !keyOn ) {
|
if ( !keyOn ) {
|
||||||
@ -590,7 +589,7 @@ Bits INLINE Operator::GetSample( Bits modulation ) {
|
|||||||
Bitu vol = ForwardVolume();
|
Bitu vol = ForwardVolume();
|
||||||
if ( ENV_SILENT( vol ) ) {
|
if ( ENV_SILENT( vol ) ) {
|
||||||
//Simply forward the wave
|
//Simply forward the wave
|
||||||
waveIndex += waveAdd;
|
waveIndex += waveCurrent;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
Bitu index = ForwardWave();
|
Bitu index = ForwardWave();
|
||||||
@ -604,6 +603,7 @@ Operator::Operator() {
|
|||||||
freqMul = 0;
|
freqMul = 0;
|
||||||
waveIndex = 0;
|
waveIndex = 0;
|
||||||
waveAdd = 0;
|
waveAdd = 0;
|
||||||
|
waveCurrent = 0;
|
||||||
keyOn = 0;
|
keyOn = 0;
|
||||||
ksr = 0;
|
ksr = 0;
|
||||||
reg20 = 0;
|
reg20 = 0;
|
||||||
@ -614,8 +614,9 @@ Operator::Operator() {
|
|||||||
SetState( OFF );
|
SetState( OFF );
|
||||||
rateZero = (1 << OFF);
|
rateZero = (1 << OFF);
|
||||||
sustainLevel = ENV_MAX;
|
sustainLevel = ENV_MAX;
|
||||||
activeLevel = ENV_MAX;
|
currentLevel = ENV_MAX;
|
||||||
totalLevel = ENV_MAX;
|
totalLevel = ENV_MAX;
|
||||||
|
volume = ENV_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -786,7 +787,7 @@ void Channel::ResetC0( const Chip* chip ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template< bool opl3Mode>
|
template< bool opl3Mode>
|
||||||
void Channel::GeneratePercussion( Bit32s* output ) {
|
INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) {
|
||||||
Channel* chan = this;
|
Channel* chan = this;
|
||||||
|
|
||||||
//BassDrum
|
//BassDrum
|
||||||
@ -805,8 +806,8 @@ void Channel::GeneratePercussion( Bit32s* output ) {
|
|||||||
Operator* op2 = ( this + 1 )->Op(0);
|
Operator* op2 = ( this + 1 )->Op(0);
|
||||||
Operator* op4 = ( this + 2 )->Op(0);
|
Operator* op4 = ( this + 2 )->Op(0);
|
||||||
|
|
||||||
//Precalculate stuff used by other oupts
|
//Precalculate stuff used by other outputs
|
||||||
Bit32u noiseBit = rand() & 0x2;
|
Bit32u noiseBit = (chip->ForwardNoise() & 0x1) << 1;
|
||||||
Bit32u c2 = op2->ForwardWave();
|
Bit32u c2 = op2->ForwardWave();
|
||||||
//(bit 7 ^ bit 2) | bit 3 -> combined in bit 1
|
//(bit 7 ^ bit 2) | bit 3 -> combined in bit 1
|
||||||
Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 );
|
Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 );
|
||||||
@ -832,7 +833,10 @@ void Channel::GeneratePercussion( Bit32s* output ) {
|
|||||||
sample += op3->GetWave( sdIndex, sdVol );
|
sample += op3->GetWave( sdIndex, sdVol );
|
||||||
}
|
}
|
||||||
//Tom-tom
|
//Tom-tom
|
||||||
sample += op4->GetSample( 0 );
|
Bit32u ttVol = op4->ForwardVolume();
|
||||||
|
if ( !ENV_SILENT( ttVol ) ) {
|
||||||
|
sample += op4->GetWave( c4, ttVol );
|
||||||
|
}
|
||||||
//Top-Cymbal
|
//Top-Cymbal
|
||||||
Operator* op5 = ( this + 2 )->Op(1);
|
Operator* op5 = ( this + 2 )->Op(1);
|
||||||
Bit32u tcVol = op5->ForwardVolume();
|
Bit32u tcVol = op5->ForwardVolume();
|
||||||
@ -850,7 +854,7 @@ void Channel::GeneratePercussion( Bit32s* output ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<SynthMode mode>
|
template<SynthMode mode>
|
||||||
Channel* Channel::BlockTemplate( ) {
|
Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) {
|
||||||
switch( mode ) {
|
switch( mode ) {
|
||||||
case sm2AM:
|
case sm2AM:
|
||||||
case sm3AM:
|
case sm3AM:
|
||||||
@ -891,16 +895,24 @@ Channel* Channel::BlockTemplate( ) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for ( Bitu i = 0; i < Work.samples; i++ ) {
|
//Init the operators with the the current vibrato and tremolo values
|
||||||
Work.vibrato = Work.vibTable[i];
|
Op( 0 )->Prepare( chip );
|
||||||
Work.tremolo = Work.tremTable[i];
|
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
|
//Early out for percussion handlers
|
||||||
if ( mode == sm2Percussion ) {
|
if ( mode == sm2Percussion ) {
|
||||||
GeneratePercussion<false>( Work.output + i );
|
GeneratePercussion<false>( chip, output + i );
|
||||||
continue; //Prevent some unitialized value bitching
|
continue; //Prevent some unitialized value bitching
|
||||||
} else if ( mode == sm3Percussion ) {
|
} else if ( mode == sm3Percussion ) {
|
||||||
GeneratePercussion<true>( Work.output + i * 2 );
|
GeneratePercussion<true>( chip, output + i * 2 );
|
||||||
continue; //Prevent some unitialized value bitching
|
continue; //Prevent some unitialized value bitching
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -936,7 +948,7 @@ Channel* Channel::BlockTemplate( ) {
|
|||||||
switch( mode ) {
|
switch( mode ) {
|
||||||
case sm2AM:
|
case sm2AM:
|
||||||
case sm2FM:
|
case sm2FM:
|
||||||
Work.output[ i ] += sample;
|
output[ i ] += sample;
|
||||||
break;
|
break;
|
||||||
case sm3AM:
|
case sm3AM:
|
||||||
case sm3FM:
|
case sm3FM:
|
||||||
@ -944,8 +956,8 @@ Channel* Channel::BlockTemplate( ) {
|
|||||||
case sm3AMFM:
|
case sm3AMFM:
|
||||||
case sm3FMAM:
|
case sm3FMAM:
|
||||||
case sm3AMAM:
|
case sm3AMAM:
|
||||||
Work.output[ i * 2 + 0 ] += sample & maskLeft;
|
output[ i * 2 + 0 ] += sample & maskLeft;
|
||||||
Work.output[ i * 2 + 1 ] += sample & maskRight;
|
output[ i * 2 + 1 ] += sample & maskRight;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -979,31 +991,53 @@ Chip::Chip() {
|
|||||||
opl3Active = 0;
|
opl3Active = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INLINE Bit32u Chip::ForwardNoise() {
|
||||||
Bit8u Chip::ForwardTremolo( ) {
|
noiseCounter += noiseAdd;
|
||||||
tremoloCounter += tremoloAdd;
|
Bitu count = noiseCounter >> LFO_SH;
|
||||||
if ( tremoloCounter >= (TREMOLO_TABLE << TREMOLO_SH) ) {
|
noiseCounter &= WAVE_MASK;
|
||||||
tremoloCounter -= TREMOLO_TABLE << TREMOLO_SH;
|
for ( ; count > 0; --count ) {
|
||||||
|
//Noise calculation from mame
|
||||||
|
noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) );
|
||||||
|
noiseValue >>= 1;
|
||||||
}
|
}
|
||||||
Bitu index = tremoloCounter >> TREMOLO_SH;
|
return noiseValue;
|
||||||
return TremoloTable[ index ] >> tremoloShift;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Bit8s Chip::ForwardVibrato( ) {
|
INLINE Bit32u Chip::ForwardLFO( Bit32u samples ) {
|
||||||
vibratoCounter += vibratoAdd;
|
//Current vibrato value, runs 4x slower than tremolo
|
||||||
Bitu index = vibratoCounter >> VIBRATO_SH;
|
vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7;
|
||||||
//Vibrato shift, basically makes the shift greater reducing the actual final value
|
vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength;
|
||||||
return VibratoTable[index & 7] + vibratoShift;
|
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 ) {
|
void Chip::WriteBD( Bit8u val ) {
|
||||||
Bit8u change = regBD ^ val;
|
Bit8u change = regBD ^ val;
|
||||||
if ( !change )
|
if ( !change )
|
||||||
return;
|
return;
|
||||||
regBD = val;
|
regBD = val;
|
||||||
//TODO could do this with shift and xor?
|
//TODO could do this with shift and xor?
|
||||||
vibratoShift = (val & 0x40) ? 0x00 : 0x01;
|
vibratoStrength = (val & 0x40) ? 0x00 : 0x01;
|
||||||
tremoloShift = (val & 0x80) ? 0x00 : 0x02;
|
tremoloStrength = (val & 0x80) ? 0x00 : 0x02;
|
||||||
if ( val & 0x20 ) {
|
if ( val & 0x20 ) {
|
||||||
//Drum was just enabled, make sure channel 6 has the right synth
|
//Drum was just enabled, make sure channel 6 has the right synth
|
||||||
if ( change & 0x20 ) {
|
if ( change & 0x20 ) {
|
||||||
@ -1150,53 +1184,69 @@ Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chip::GenerateBlock2( Bitu samples ) {
|
void Chip::GenerateBlock2( Bitu total, Bit32s* output ) {
|
||||||
Work.samples = samples;
|
while ( total > 0 ) {
|
||||||
for ( Bitu i = 0; i < Work.samples; i++ ) {
|
Bit32u samples = ForwardLFO( total );
|
||||||
Work.vibTable[i] = ForwardVibrato();
|
for ( Bitu i = 0; i < samples; i++ ) {
|
||||||
Work.tremTable[i] = ForwardTremolo();
|
output[i] = 0;
|
||||||
Work.output[i] = 0;
|
|
||||||
}
|
}
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for( Channel* ch = chan; ch < chan + 9; ) {
|
for( Channel* ch = chan; ch < chan + 9; ) {
|
||||||
count++;
|
count++;
|
||||||
ch = (ch->*(ch->synthHandler))();
|
ch = (ch->*(ch->synthHandler))( this, samples, output );
|
||||||
|
}
|
||||||
|
total -= samples;
|
||||||
|
output += samples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chip::GenerateBlock3( Bitu samples ) {
|
void Chip::GenerateBlock3( Bitu total, Bit32s* output ) {
|
||||||
Work.samples = samples;
|
while ( total > 0 ) {
|
||||||
for ( Bitu i = 0; i < Work.samples; i++ ) {
|
Bit32u samples = ForwardLFO( total );
|
||||||
Work.vibTable[i] = ForwardVibrato();
|
for ( Bitu i = 0; i < samples; i++ ) {
|
||||||
Work.tremTable[i] = ForwardTremolo();
|
output[i * 2 + 0 ] = 0;
|
||||||
Work.output[i*2 + 0] = 0;
|
output[i * 2 + 1 ] = 0;
|
||||||
Work.output[i*2 + 1] = 0;
|
|
||||||
}
|
}
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for( Channel* ch = chan; ch < chan + 18; ) {
|
for( Channel* ch = chan; ch < chan + 18; ) {
|
||||||
count++;
|
count++;
|
||||||
ch = (ch->*(ch->synthHandler))();
|
ch = (ch->*(ch->synthHandler))( this, samples, output );
|
||||||
|
}
|
||||||
|
total -= samples;
|
||||||
|
output += samples * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chip::Setup( Bit32u rate ) {
|
void Chip::Setup( Bit32u rate ) {
|
||||||
//Vibrato forwards every 1024 samples
|
double original = OPLRATE;
|
||||||
vibratoAdd = (Bit32u)((double)rate * (double)( 1 << (VIBRATO_SH - 10) ) / OPLRATE);
|
// double original = rate;
|
||||||
vibratoCounter = 0;
|
double scale = original / (double)rate;
|
||||||
//tremolo forwards every 64 samples
|
|
||||||
//We use a 52 entry table, real is 210, so repeat each sample an extra 4 times
|
//Noise counter is run at the same precision as general waves
|
||||||
tremoloAdd = (Bit32u)((double)rate * (double)( 1 << (TREMOLO_SH - 6 - 2) ) / OPLRATE);
|
noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
|
||||||
tremoloCounter = 0;
|
noiseCounter = 0;
|
||||||
//10 bits of frequency counter
|
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
|
//With higher octave this gets shifted up
|
||||||
//-1 since the freqCreateTable = *2
|
//-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++ ) {
|
for ( int i = 0; i < 16; i++ ) {
|
||||||
//Use rounding with 0.5
|
freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] );
|
||||||
freqMul[i] = (Bit32u)( 0.5 + scale * 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
|
//-3 since the real envelope takes 8 steps to reach the single value we supply
|
||||||
for ( Bit8u i = 0; i < 76; i++ ) {
|
for ( Bit8u i = 0; i < 76; i++ ) {
|
||||||
Bit8u index, shift;
|
Bit8u index, shift;
|
||||||
@ -1456,12 +1506,15 @@ void Handler::WriteReg( Bit32u addr, Bit8u val ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Handler::Generate( MixerChannel* chan, Bitu samples ) {
|
void Handler::Generate( MixerChannel* chan, Bitu samples ) {
|
||||||
|
Bit32s buffer[ 512 * 2 ];
|
||||||
|
if ( samples > 512 )
|
||||||
|
samples = 512;
|
||||||
if ( !chip.opl3Active ) {
|
if ( !chip.opl3Active ) {
|
||||||
chip.GenerateBlock2( samples );
|
chip.GenerateBlock2( samples, buffer );
|
||||||
chan->AddSamples_m32( samples, Work.output );
|
chan->AddSamples_m32( samples, buffer );
|
||||||
} else {
|
} else {
|
||||||
chip.GenerateBlock3( samples );
|
chip.GenerateBlock3( samples, buffer );
|
||||||
chan->AddSamples_s32( samples, Work.output );
|
chan->AddSamples_s32( samples, buffer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,10 +28,6 @@
|
|||||||
|
|
||||||
//Select the type of wave generator routine
|
//Select the type of wave generator routine
|
||||||
#define DBOPL_WAVE WAVE_TABLEMUL
|
#define DBOPL_WAVE WAVE_TABLEMUL
|
||||||
//Enable vibrato in the output
|
|
||||||
#define DBOPL_VIBRATO
|
|
||||||
//Enable tremolo in the output
|
|
||||||
#define DBOPL_TREMOLO
|
|
||||||
|
|
||||||
namespace DBOPL {
|
namespace DBOPL {
|
||||||
|
|
||||||
@ -44,20 +40,21 @@ typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef Bits ( DBOPL::Operator::*VolumeHandler) ( );
|
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
|
//Different synth modes that can generate blocks of data
|
||||||
typedef enum {
|
typedef enum {
|
||||||
smNone,
|
|
||||||
sm2AM,
|
sm2AM,
|
||||||
sm2FM,
|
sm2FM,
|
||||||
sm2Percussion,
|
|
||||||
sm3AM,
|
sm3AM,
|
||||||
sm3FM,
|
sm3FM,
|
||||||
|
sm4Start,
|
||||||
sm3FMFM,
|
sm3FMFM,
|
||||||
sm3AMFM,
|
sm3AMFM,
|
||||||
sm3FMAM,
|
sm3FMAM,
|
||||||
sm3AMAM,
|
sm3AMAM,
|
||||||
|
sm6Start,
|
||||||
|
sm2Percussion,
|
||||||
sm3Percussion,
|
sm3Percussion,
|
||||||
} SynthMode;
|
} SynthMode;
|
||||||
|
|
||||||
@ -95,14 +92,16 @@ public:
|
|||||||
Bit32u waveStart;
|
Bit32u waveStart;
|
||||||
#endif
|
#endif
|
||||||
Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
|
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 chanData; //Frequency/octave and derived data coming from whatever channel controls this
|
||||||
Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
|
Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
|
||||||
Bit32u vibrato; //Scaled up vibrato strength
|
Bit32u vibrato; //Scaled up vibrato strength
|
||||||
Bit32s sustainLevel; //When stopping at sustain level stop here
|
Bit32s sustainLevel; //When stopping at sustain level stop here
|
||||||
Bit32s totalLevel; //totalLeve is added to every generated volume
|
Bit32s totalLevel; //totalLevel is added to every generated volume
|
||||||
Bit32s activeLevel; //The currently active volume
|
Bit32u currentLevel; //totalLevel + tremolo
|
||||||
|
Bit32s volume; //The currently active volume
|
||||||
|
|
||||||
Bit32u attackAdd; //Timers for the different states of the envelope
|
Bit32u attackAdd; //Timers for the different states of the envelope
|
||||||
Bit32u decayAdd;
|
Bit32u decayAdd;
|
||||||
@ -138,6 +137,8 @@ public:
|
|||||||
void WriteE0( const Chip* chip, Bit8u val );
|
void WriteE0( const Chip* chip, Bit8u val );
|
||||||
|
|
||||||
bool Silent() const;
|
bool Silent() const;
|
||||||
|
void Prepare( const Chip* chip );
|
||||||
|
|
||||||
void KeyOn( Bit8u mask);
|
void KeyOn( Bit8u mask);
|
||||||
void KeyOff( Bit8u mask);
|
void KeyOff( Bit8u mask);
|
||||||
|
|
||||||
@ -182,20 +183,23 @@ struct Channel {
|
|||||||
|
|
||||||
//call this for the first channel
|
//call this for the first channel
|
||||||
template< bool opl3Mode >
|
template< bool opl3Mode >
|
||||||
void GeneratePercussion( Bit32s* output );
|
void GeneratePercussion( Chip* chip, Bit32s* output );
|
||||||
|
|
||||||
//Generate blocks of data in specific modes
|
//Generate blocks of data in specific modes
|
||||||
template<SynthMode mode>
|
template<SynthMode mode>
|
||||||
Channel* BlockTemplate( );
|
Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output );
|
||||||
Channel();
|
Channel();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Chip {
|
struct Chip {
|
||||||
//This is used as the base counter for vibrato and tremolo
|
//This is used as the base counter for vibrato and tremolo
|
||||||
Bit32u tremoloCounter;
|
Bit32u lfoCounter;
|
||||||
Bit32u tremoloAdd;
|
Bit32u lfoAdd;
|
||||||
Bit32u vibratoCounter;
|
|
||||||
Bit32u vibratoAdd;
|
|
||||||
|
Bit32u noiseCounter;
|
||||||
|
Bit32u noiseAdd;
|
||||||
|
Bit32u noiseValue;
|
||||||
|
|
||||||
//Frequency scales for the different multiplications
|
//Frequency scales for the different multiplications
|
||||||
Bit32u freqMul[16];
|
Bit32u freqMul[16];
|
||||||
@ -211,23 +215,29 @@ struct Chip {
|
|||||||
Bit8u reg08;
|
Bit8u reg08;
|
||||||
Bit8u reg04;
|
Bit8u reg04;
|
||||||
Bit8u regBD;
|
Bit8u regBD;
|
||||||
|
Bit8u vibratoIndex;
|
||||||
|
Bit8u tremoloIndex;
|
||||||
|
Bit8s vibratoSign;
|
||||||
Bit8u vibratoShift;
|
Bit8u vibratoShift;
|
||||||
Bit8u tremoloShift;
|
Bit8u tremoloValue;
|
||||||
|
Bit8u vibratoStrength;
|
||||||
|
Bit8u tremoloStrength;
|
||||||
//Mask for allowed wave forms
|
//Mask for allowed wave forms
|
||||||
Bit8u waveFormMask;
|
Bit8u waveFormMask;
|
||||||
//0 or -1 when enabled
|
//0 or -1 when enabled
|
||||||
Bit8s opl3Active;
|
Bit8s opl3Active;
|
||||||
|
|
||||||
Bit8u ForwardTremolo();
|
//Return the maximum amount of samples before and LFO change
|
||||||
Bit8s ForwardVibrato();
|
Bit32u ForwardLFO( Bit32u samples );
|
||||||
|
Bit32u ForwardNoise();
|
||||||
|
|
||||||
void WriteBD( Bit8u val );
|
void WriteBD( Bit8u val );
|
||||||
void WriteReg(Bit32u reg, Bit8u val );
|
void WriteReg(Bit32u reg, Bit8u val );
|
||||||
|
|
||||||
Bit32u WriteAddr( Bit32u port, Bit8u val );
|
Bit32u WriteAddr( Bit32u port, Bit8u val );
|
||||||
|
|
||||||
void GenerateBlock2( Bitu samples );
|
void GenerateBlock2( Bitu samples, Bit32s* output );
|
||||||
void GenerateBlock3( Bitu samples );
|
void GenerateBlock3( Bitu samples, Bit32s* output );
|
||||||
|
|
||||||
void Generate( Bit32u samples );
|
void Generate( Bit32u samples );
|
||||||
void Setup( Bit32u r );
|
void Setup( Bit32u r );
|
||||||
|
@ -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
|
* 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
|
* 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.
|
* 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 <string.h>
|
#include <string.h>
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
@ -56,6 +56,7 @@ static struct {
|
|||||||
|
|
||||||
Bitu state;
|
Bitu state;
|
||||||
Bitu interface_det;
|
Bitu interface_det;
|
||||||
|
Bitu interface_det_ext;
|
||||||
} disney;
|
} disney;
|
||||||
|
|
||||||
#define DS_IDLE 0
|
#define DS_IDLE 0
|
||||||
@ -71,12 +72,13 @@ static void DISNEY_disable(Bitu) {
|
|||||||
disney.chan->Enable(false);
|
disney.chan->Enable(false);
|
||||||
delete disney.mo;
|
delete disney.mo;
|
||||||
}
|
}
|
||||||
disney.interface_det = 0;
|
|
||||||
disney.leader = 0;
|
disney.leader = 0;
|
||||||
disney.last_used = 0;
|
disney.last_used = 0;
|
||||||
disney.mo = 0;
|
disney.mo = 0;
|
||||||
disney.state = DS_IDLE;
|
disney.state = DS_IDLE;
|
||||||
disney.interface_det = 0;
|
disney.interface_det = 0;
|
||||||
|
disney.interface_det_ext = 0;
|
||||||
|
disney.stereo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DISNEY_enable(Bitu freq) {
|
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].buffer[disney.da[0].used] = disney.data;
|
||||||
disney.da[0].used++;
|
disney.da[0].used++;
|
||||||
} //else LOG_MSG("disney overflow 0");
|
} //else LOG_MSG("disney overflow 0");
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -208,6 +209,7 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) {
|
|||||||
if((disney.control & 0x2) && !(val & 0x2)) {
|
if((disney.control & 0x2) && !(val & 0x2)) {
|
||||||
if(disney.state != DS_RUNNING) {
|
if(disney.state != DS_RUNNING) {
|
||||||
disney.interface_det = 0;
|
disney.interface_det = 0;
|
||||||
|
disney.interface_det_ext = 0;
|
||||||
DISNEY_analyze(1);
|
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.control & 0x1) && !(val & 0x1)) {
|
||||||
if(disney.state != DS_RUNNING) {
|
if(disney.state != DS_RUNNING) {
|
||||||
disney.interface_det = 0;
|
disney.interface_det = 0;
|
||||||
|
disney.interface_det_ext = 0;
|
||||||
DISNEY_analyze(0);
|
DISNEY_analyze(0);
|
||||||
}
|
}
|
||||||
// stereo channel latch
|
// stereo channel latch
|
||||||
@ -230,6 +233,24 @@ static void disney_write(Bitu port,Bitu val,Bitu iolen) {
|
|||||||
} //else LOG_MSG("disney overflow 0");
|
} //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);
|
// LOG_WARN("DISNEY:Control write %x",val);
|
||||||
if (val&0x10) LOG(LOG_MISC,LOG_ERROR)("DISNEY:Parallel IRQ Enabled");
|
if (val&0x10) LOG(LOG_MISC,LOG_ERROR)("DISNEY:Parallel IRQ Enabled");
|
||||||
disney.control=val;
|
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) {
|
static Bitu disney_read(Bitu port,Bitu iolen) {
|
||||||
|
Bitu retval;
|
||||||
switch (port-DISNEY_BASE) {
|
switch (port-DISNEY_BASE) {
|
||||||
case 0: /* Data Port */
|
case 0: /* Data Port */
|
||||||
// LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from 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;
|
break;
|
||||||
case 1: /* Status Port */
|
case 1: /* Status Port */
|
||||||
// LOG(LOG_MISC,"DISNEY:Read from status port %X",disney.status);
|
// LOG(LOG_MISC,"DISNEY:Read from status port %X",disney.status);
|
||||||
if (disney.leader && disney.leader->used >= 16) return 0x40;
|
retval = 0x07;//0x40; // Stereo-on-1 and (or) New-Stereo DACs present
|
||||||
/* Stereo-on-1 and (or) New-Stereo DACs present */
|
if(disney.interface_det_ext > 5) {
|
||||||
if(!(disney.data&0x80)) return 0xc4;
|
if (disney.leader && disney.leader->used >= 16){
|
||||||
else return 0x0;
|
retval |= 0x40; // ack
|
||||||
|
retval &= ~0x4; // interrupt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!(disney.data&0x80)) retval |= 0x80; // pin 9 is wired to pin 11
|
||||||
|
return retval;
|
||||||
break;
|
break;
|
||||||
case 2: /* Control Port */
|
case 2: /* Control Port */
|
||||||
LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from control port");
|
LOG(LOG_MISC,LOG_NORMAL)("DISNEY:Read from control port");
|
||||||
|
@ -64,7 +64,6 @@ Revision History:
|
|||||||
|
|
||||||
//#include "driver.h" /* use M.A.M.E. */
|
//#include "driver.h" /* use M.A.M.E. */
|
||||||
#include "fmopl.h"
|
#include "fmopl.h"
|
||||||
#include "config.h" // INLINE
|
|
||||||
|
|
||||||
#ifndef PI
|
#ifndef PI
|
||||||
#define PI 3.14159265358979323846
|
#define PI 3.14159265358979323846
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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"
|
#include "dosbox.h"
|
||||||
|
|
||||||
@ -951,7 +951,8 @@ public:
|
|||||||
isIpxServer = true;
|
isIpxServer = true;
|
||||||
ConnectToServer("localhost");
|
ConnectToServer("localhost");
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
WriteOut("IPX Tunneling Server already started\n");
|
WriteOut("IPX Tunneling Server already started\n");
|
||||||
|
@ -639,11 +639,7 @@ void MIXER_Init(Section* sec) {
|
|||||||
SDL_AudioSpec obtained;
|
SDL_AudioSpec obtained;
|
||||||
|
|
||||||
spec.freq=mixer.freq;
|
spec.freq=mixer.freq;
|
||||||
#ifdef HW_RVL
|
|
||||||
spec.format=AUDIO_S16MSB;
|
|
||||||
#else
|
|
||||||
spec.format=AUDIO_S16SYS;
|
spec.format=AUDIO_S16SYS;
|
||||||
#endif
|
|
||||||
spec.channels=2;
|
spec.channels=2;
|
||||||
spec.callback=MIXER_CallBack;
|
spec.callback=MIXER_CallBack;
|
||||||
spec.userdata=NULL;
|
spec.userdata=NULL;
|
||||||
|
@ -45,8 +45,8 @@ static Bit32s tremval_const[BLOCKBUF_SIZE];
|
|||||||
// vibrato value tables (used per-operator)
|
// vibrato value tables (used per-operator)
|
||||||
static Bit32s vibval_var1[BLOCKBUF_SIZE];
|
static Bit32s vibval_var1[BLOCKBUF_SIZE];
|
||||||
static Bit32s vibval_var2[BLOCKBUF_SIZE];
|
static Bit32s vibval_var2[BLOCKBUF_SIZE];
|
||||||
static Bit32s vibval_var3[BLOCKBUF_SIZE];
|
//static Bit32s vibval_var3[BLOCKBUF_SIZE];
|
||||||
static Bit32s vibval_var4[BLOCKBUF_SIZE];
|
//static Bit32s vibval_var4[BLOCKBUF_SIZE];
|
||||||
|
|
||||||
// vibrato/trmolo value table pointers
|
// vibrato/trmolo value table pointers
|
||||||
static Bit32s *vibval1, *vibval2, *vibval3, *vibval4;
|
static Bit32s *vibval1, *vibval2, *vibval3, *vibval4;
|
||||||
@ -132,8 +132,18 @@ static Bit32u wavestart[8] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// envelope generator function constants
|
// envelope generator function constants
|
||||||
static fltype attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744};
|
static fltype attackconst[4] = {
|
||||||
static fltype decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608};
|
(fltype)(1/2.82624),
|
||||||
|
(fltype)(1/2.25280),
|
||||||
|
(fltype)(1/1.88416),
|
||||||
|
(fltype)(1/1.59744)
|
||||||
|
};
|
||||||
|
static fltype decrelconst[4] = {
|
||||||
|
(fltype)(1/39.28064),
|
||||||
|
(fltype)(1/31.41608),
|
||||||
|
(fltype)(1/26.17344),
|
||||||
|
(fltype)(1/22.44608)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void operator_advance(op_type* op_pt, Bit32s vib) {
|
void operator_advance(op_type* op_pt, Bit32s vib) {
|
||||||
@ -281,9 +291,9 @@ void operator_attack(op_type* op_pt) {
|
|||||||
op_pt->amp = 1.0;
|
op_pt->amp = 1.0;
|
||||||
op_pt->step_amp = 1.0;
|
op_pt->step_amp = 1.0;
|
||||||
}
|
}
|
||||||
op_pt->step_skip_pos <<= 1;
|
op_pt->step_skip_pos_a <<= 1;
|
||||||
if (op_pt->step_skip_pos==0) op_pt->step_skip_pos = 1;
|
if (op_pt->step_skip_pos_a==0) op_pt->step_skip_pos_a = 1;
|
||||||
if (op_pt->step_skip_pos & op_pt->env_step_skip_a) { // check if required to skip next step
|
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;
|
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_a = 0;
|
||||||
op[i].env_step_d = 0;
|
op[i].env_step_d = 0;
|
||||||
op[i].env_step_r = 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;
|
op[i].env_step_skip_a = 0;
|
||||||
|
|
||||||
#if defined(OPLTYPE_IS_OPL3)
|
#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) +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<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC));
|
||||||
wavtable[i] = wavtable[(i<<1) +WAVEPREC];
|
wavtable[i] = wavtable[(i<<1) +WAVEPREC];
|
||||||
// table to be verified, alternative: (zero-less)
|
// alternative: (zero-less)
|
||||||
/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1)-1)*PI/WAVEPREC));
|
/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+1)*PI/WAVEPREC));
|
||||||
wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1) )*PI/WAVEPREC));
|
wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+3)*PI/WAVEPREC));
|
||||||
wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */
|
wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */
|
||||||
}
|
}
|
||||||
for (i=0;i<(WAVEPREC>>3);i++) {
|
for (i=0;i<(WAVEPREC>>3);i++) {
|
||||||
@ -589,7 +599,6 @@ void adlib_init(Bit32u samplerate) {
|
|||||||
|
|
||||||
void adlib_write(Bitu idx, Bit8u val) {
|
void adlib_write(Bitu idx, Bit8u val) {
|
||||||
Bit32u second_set = idx&0x100;
|
Bit32u second_set = idx&0x100;
|
||||||
Bit8u old_val = adlibreg[idx];
|
|
||||||
adlibreg[idx] = val;
|
adlibreg[idx] = val;
|
||||||
|
|
||||||
switch (idx&0xf0) {
|
switch (idx&0xf0) {
|
||||||
@ -910,7 +919,7 @@ void adlib_write_index(Bitu port, Bit8u val) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void INLINE clipit16(Bit32s ival, Bit16s* outval) {
|
static void OPL_INLINE clipit16(Bit32s ival, Bit16s* outval) {
|
||||||
if (ival<32768) {
|
if (ival<32768) {
|
||||||
if (ival>-32769) {
|
if (ival>-32769) {
|
||||||
*outval=(Bit16s)ival;
|
*outval=(Bit16s)ival;
|
||||||
|
@ -42,6 +42,13 @@ typedef uint8_t Bit8u;
|
|||||||
typedef int8_t Bit8s;
|
typedef int8_t Bit8s;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
define attribution that inlines/forces inlining of a function (optional)
|
||||||
|
*/
|
||||||
|
#define OPL_INLINE INLINE
|
||||||
|
|
||||||
|
|
||||||
#undef NUM_CHANNELS
|
#undef NUM_CHANNELS
|
||||||
#if defined(OPLTYPE_IS_OPL3)
|
#if defined(OPLTYPE_IS_OPL3)
|
||||||
#define NUM_CHANNELS 18
|
#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
|
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 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)
|
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)
|
Bits env_step_skip_a; // bitmask that determines if a step is skipped (respective bit is zero then)
|
||||||
|
|
||||||
#if defined(OPLTYPE_IS_OPL3)
|
#if defined(OPLTYPE_IS_OPL3)
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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 <math.h>
|
#include <math.h>
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
@ -305,15 +305,21 @@ static void PCSPEAKER_CallBack(Bitu len) {
|
|||||||
if(spkr.chan) spkr.chan->AddSamples_m16(len,(Bit16s*)MixTemp);
|
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
|
//Turn off speaker after 10 seconds of idle or one second idle when in off mode
|
||||||
|
bool turnoff = false;
|
||||||
Bitu test_ticks = PIC_Ticks;
|
Bitu test_ticks = PIC_Ticks;
|
||||||
if ((spkr.last_ticks+10000)<test_ticks) {
|
if ((spkr.last_ticks + 10000) < test_ticks) turnoff = true;
|
||||||
spkr.last_ticks=0;
|
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);
|
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) <test_ticks)) {
|
|
||||||
spkr.last_ticks=0;
|
|
||||||
if(spkr.chan) spkr.chan->Enable(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
class PCSPEAKER:public Module_base {
|
class PCSPEAKER:public Module_base {
|
||||||
private:
|
private:
|
||||||
|
@ -50,16 +50,19 @@ Note: Each read or write of this register will cycle through first the
|
|||||||
|
|
||||||
enum {DAC_READ,DAC_WRITE};
|
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;
|
Bitu maskIndex = index & vga.dac.pel_mask;
|
||||||
vga.dac.xlat16[index] = ((vga.dac.rgb[maskIndex].blue>>1)&0x1f) |
|
VGA_DAC_SendColor( index, maskIndex );
|
||||||
(((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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_p3c6(Bitu port,Bitu val,Bitu iolen) {
|
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 */
|
/* Check for attributes and DAC entry link */
|
||||||
for (Bitu i=0;i<16;i++) {
|
for (Bitu i=0;i<16;i++) {
|
||||||
if (vga.dac.combine[i]==vga.dac.write_index) {
|
if (vga.dac.combine[i]==vga.dac.write_index) {
|
||||||
vga.dac.xlat16[i] = (
|
VGA_DAC_SendColor( i, vga.dac.write_index );
|
||||||
(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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,16 +180,8 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) {
|
|||||||
case M_VGA:
|
case M_VGA:
|
||||||
// used by copper demo; almost no video card seems to suport it
|
// used by copper demo; almost no video card seems to suport it
|
||||||
if(!IS_VGA_ARCH || (svgaCard!=SVGA_None)) break;
|
if(!IS_VGA_ARCH || (svgaCard!=SVGA_None)) break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vga.dac.xlat16[attr] = ((vga.dac.rgb[pal].blue>>1)&0x1f) |
|
VGA_DAC_SendColor( attr, pal );
|
||||||
(((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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +192,7 @@ void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) {
|
|||||||
vga.dac.rgb[entry].blue=blue;
|
vga.dac.rgb[entry].blue=blue;
|
||||||
for (Bitu i=0;i<16;i++)
|
for (Bitu i=0;i<16;i++)
|
||||||
if (vga.dac.combine[i]==entry)
|
if (vga.dac.combine[i]==entry)
|
||||||
RENDER_SetPal(i,red << 2,green << 2,blue << 2);
|
VGA_DAC_SendColor( i, i );
|
||||||
}
|
}
|
||||||
|
|
||||||
void VGA_SetupDAC(void) {
|
void VGA_SetupDAC(void) {
|
||||||
|
@ -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
|
* 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
|
* 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.
|
* 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 <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -79,16 +79,16 @@ public:
|
|||||||
SetName("EMMXXXX0");
|
SetName("EMMXXXX0");
|
||||||
GEMMIS_seg=0;
|
GEMMIS_seg=0;
|
||||||
}
|
}
|
||||||
bool Read(Bit8u * data,Bit16u * size) { return false;}
|
bool Read(Bit8u * /*data*/,Bit16u * /*size*/) { return false;}
|
||||||
bool Write(Bit8u * data,Bit16u * size){
|
bool Write(Bit8u * /*data*/,Bit16u * /*size*/){
|
||||||
LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device");
|
LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool Seek(Bit32u * pos,Bit32u type){return false;}
|
bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;}
|
||||||
bool Close(){return false;}
|
bool Close(){return false;}
|
||||||
Bit16u GetInformation(void){return 0xc080;}
|
Bit16u GetInformation(void){return 0xc080;}
|
||||||
bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
|
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:
|
private:
|
||||||
Bit8u cache;
|
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+0x0a+frnr,0x03); // frame type: EMS frame in 64k page
|
||||||
mem_writeb(GEMMIS_addr+0x0b+frnr,0xff); // owner: NONE
|
mem_writeb(GEMMIS_addr+0x0b+frnr,0xff); // owner: NONE
|
||||||
mem_writew(GEMMIS_addr+0x0c+frnr,0x7fff); // no logical page number
|
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
|
mem_writeb(GEMMIS_addr+0x0f+frnr,0x00); // EMS frame
|
||||||
}
|
}
|
||||||
/* build non-EMS ROM frames (0xf000-0x10000) */
|
/* 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) {
|
while (emm_handles[handle].pages != NULL_HANDLE) {
|
||||||
if (++handle >= EMM_MAX_HANDLES) {return EMM_OUT_OF_HANDLES;}
|
if (++handle >= EMM_MAX_HANDLES) {return EMM_OUT_OF_HANDLES;}
|
||||||
}
|
}
|
||||||
MemHandle mem = MEM_AllocatePages(pages*4,false);
|
MemHandle mem = 0;
|
||||||
|
if (pages) {
|
||||||
|
mem = MEM_AllocatePages(pages*4,false);
|
||||||
if (!mem) E_Exit("EMS:Memory allocation failure");
|
if (!mem) E_Exit("EMS:Memory allocation failure");
|
||||||
|
}
|
||||||
emm_handles[handle].pages = pages;
|
emm_handles[handle].pages = pages;
|
||||||
emm_handles[handle].mem = mem;
|
emm_handles[handle].mem = mem;
|
||||||
/* Change handle only if there is no error. */
|
/* 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) {
|
static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) {
|
||||||
/* Check for valid handle */
|
/* Check for valid handle */
|
||||||
if (!ValidHandle(handle)) return EMM_INVALID_HANDLE;
|
if (!ValidHandle(handle)) return EMM_INVALID_HANDLE;
|
||||||
|
if (emm_handles[handle].pages != 0) {
|
||||||
/* Check for enough pages */
|
/* Check for enough pages */
|
||||||
if (!MEM_ReAllocatePages(emm_handles[handle].mem,pages*4,false)) return EMM_OUT_OF_LOG;
|
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 */
|
/* Update size */
|
||||||
emm_handles[handle].pages=pages;
|
emm_handles[handle].pages=pages;
|
||||||
return EMM_NO_ERROR;
|
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) {
|
static Bit8u EMM_ReleaseMemory(Bit16u handle) {
|
||||||
/* Check for valid handle */
|
/* Check for valid handle */
|
||||||
if (!ValidHandle(handle)) return EMM_INVALID_HANDLE;
|
if (!ValidHandle(handle)) return EMM_INVALID_HANDLE;
|
||||||
|
|
||||||
// should check for saved_page_map flag here, returning an error if it's true
|
// 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
|
// as apps are required to restore the pagemap beforehand; to be checked
|
||||||
|
// if (emm_handles[handle].saved_page_map) return EMM_SAVEMAP_ERROR;
|
||||||
|
|
||||||
|
if (emm_handles[handle].pages != 0) {
|
||||||
MEM_ReleasePages(emm_handles[handle].mem);
|
MEM_ReleasePages(emm_handles[handle].mem);
|
||||||
|
}
|
||||||
/* Reset handle */
|
/* Reset handle */
|
||||||
emm_handles[handle].mem=0;
|
emm_handles[handle].mem=0;
|
||||||
if (handle==0) {
|
if (handle==0) {
|
||||||
@ -1370,7 +1384,7 @@ public:
|
|||||||
|
|
||||||
static EMS* test;
|
static EMS* test;
|
||||||
|
|
||||||
void EMS_ShutDown(Section* sec) {
|
void EMS_ShutDown(Section* /*sec*/) {
|
||||||
delete test;
|
delete test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,13 +102,13 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $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
|
#ifndef GUI__TOOLKIT_H
|
||||||
#define GUI__TOOLKIT_H
|
#define GUI__TOOLKIT_H
|
||||||
|
|
||||||
#define imin(x,y) (x<y?x:y)
|
#define imin(x,y) ((x)<(y)?(x):(y))
|
||||||
#define imax(x,y) (x>y?x:y)
|
#define imax(x,y) ((x)>(y)?(x):(y))
|
||||||
#define isign(x) (((x)<0?-1:1))
|
#define isign(x) (((x)<0?-1:1))
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
|
Loading…
Reference in New Issue
Block a user