From 82567c0bd6ab981c92b2134bf426db0fd643315d Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 20 Nov 2017 17:27:53 +0000 Subject: [PATCH] Allow for direct changing of 4op chaining without having to rewrite the algorithm mode. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4064 --- src/hardware/dbopl.cpp | 49 +++++++++++++++++++++++++----------------- src/hardware/dbopl.h | 4 +++- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index c7d61ca3..8b6df319 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -716,18 +716,23 @@ void Channel::WriteB0( const Chip* chip, Bit8u val ) { } } -void Channel::WriteC0( const Chip* chip, Bit8u val ) { +void Channel::WriteC0(const Chip* chip, Bit8u val) { Bit8u change = val ^ regC0; - if ( !change ) + if (!change) return; regC0 = val; - feedback = ( val >> 1 ) & 7; - if ( feedback ) { + feedback = (regC0 >> 1) & 7; + if (feedback) { //We shift the input to the right 10 bit wave index value feedback = 9 - feedback; - } else { + } + else { feedback = 31; } + UpdateSynth(chip); +} + +void Channel::UpdateSynth( const Chip* chip ) { //Select the new synth mode if ( chip->opl3Active ) { //4-op mode enabled for this channel @@ -761,20 +766,20 @@ void Channel::WriteC0( const Chip* chip, Bit8u val ) { } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) { //Regular dual op, am or fm - } else if ( val & 1 ) { + } else if (regC0 & 1 ) { synthHandler = &Channel::BlockTemplate< sm3AM >; } else { synthHandler = &Channel::BlockTemplate< sm3FM >; } - maskLeft = ( val & 0x10 ) ? -1 : 0; - maskRight = ( val & 0x20 ) ? -1 : 0; + maskLeft = (regC0 & 0x10 ) ? -1 : 0; + maskRight = (regC0 & 0x20 ) ? -1 : 0; //opl2 active } else { //Disable updating percussion channels if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { //Regular dual op, am or fm - } else if ( val & 1 ) { + } else if (regC0 & 1 ) { synthHandler = &Channel::BlockTemplate< sm2AM >; } else { synthHandler = &Channel::BlockTemplate< sm2FM >; @@ -782,12 +787,6 @@ void Channel::WriteC0( const Chip* chip, Bit8u val ) { } } -void Channel::ResetC0( const Chip* chip ) { - Bit8u val = regC0; - regC0 ^= 0xff; - WriteC0( chip, val ); -}; - template< bool opl3Mode> INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { Channel* chan = this; @@ -1071,7 +1070,8 @@ void Chip::WriteBD( Bit8u val ) { //Toggle keyoffs when we turn off the percussion } else if ( change & 0x20 ) { //Trigger a reset to setup the original synth handler - chan[6].ResetC0( this ); + //This makes it call + chan[6].UpdateSynth( this ); chan[6].op[0].KeyOff( 0x2 ); chan[6].op[1].KeyOff( 0x2 ); chan[7].op[0].KeyOff( 0x2 ); @@ -1096,6 +1096,14 @@ void Chip::WriteBD( Bit8u val ) { regChan->_FUNC_( this, val ); \ } +//Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers +void Chip::UpdateSynths() { + for (int i = 0; i < 18; i++) { + chan[i].UpdateSynth(this); + } +} + + void Chip::WriteReg( Bit32u reg, Bit8u val ) { Bitu index; switch ( (reg & 0xf0) >> 4 ) { @@ -1108,15 +1116,16 @@ void Chip::WriteReg( Bit32u reg, Bit8u val ) { return; //Always keep the highest bit enabled, for checking > 0x80 reg104 = 0x80 | ( val & 0x3f ); + //Switch synths when changing the 4op combinations + UpdateSynths(); } else if ( reg == 0x105 ) { //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register if ( !((opl3Active ^ val) & 1 ) ) return; opl3Active = ( val & 1 ) ? 0xff : 0; - //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers - for ( int i = 0; i < 18;i++ ) { - chan[i].ResetC0( this ); - } + //Just tupdate the synths now that opl3 most have been enabled + //This isn't how the real card handles it but need to switch to stereo generating handlers + UpdateSynths(); } else if ( reg == 0x08 ) { reg08 = val; } diff --git a/src/hardware/dbopl.h b/src/hardware/dbopl.h index c3c4d428..e33d7e35 100644 --- a/src/hardware/dbopl.h +++ b/src/hardware/dbopl.h @@ -176,10 +176,10 @@ struct Channel { void SetChanData( const Chip* chip, Bit32u data ); //Change in the chandata, check for new values and if we have to forward to operators void UpdateFrequency( const Chip* chip, Bit8u fourOp ); + void UpdateSynth(const Chip* chip); void WriteA0( const Chip* chip, Bit8u val ); void WriteB0( const Chip* chip, Bit8u val ); void WriteC0( const Chip* chip, Bit8u val ); - void ResetC0( const Chip* chip ); //call this for the first channel template< bool opl3Mode > @@ -239,6 +239,8 @@ struct Chip { void GenerateBlock2( Bitu samples, Bit32s* output ); void GenerateBlock3( Bitu samples, Bit32s* output ); + //Update the synth handlers in all channels + void UpdateSynths(); void Generate( Bit32u samples ); void Setup( Bit32u r );