Add the integer dosbox opl
Combine all the adlib stuff in 1 module Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3352
This commit is contained in:
parent
150dd14433
commit
dff27bb2c4
4 changed files with 1860 additions and 90 deletions
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: adlib.cpp,v 1.34 2009-04-17 17:24:47 c2woody Exp $ */
|
||||
/* $Id: adlib.cpp,v 1.35 2009-04-25 09:55:50 harekiet Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -24,15 +24,12 @@
|
|||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
#include "mixer.h"
|
||||
#include "pic.h"
|
||||
#include "hardware.h"
|
||||
#include "adlib.h"
|
||||
|
||||
#include "setup.h"
|
||||
#include "mapper.h"
|
||||
#include "adlib.h"
|
||||
#include "mem.h"
|
||||
#include "dbopl.h"
|
||||
|
||||
/*
|
||||
Thanks to vdmsound for nice simple way to implement this
|
||||
|
@ -188,6 +185,7 @@ namespace old_OPL3 {
|
|||
}
|
||||
|
||||
|
||||
|
||||
#define RAW_SIZE 1024
|
||||
|
||||
|
||||
|
@ -548,8 +546,8 @@ void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) {
|
|||
//Keep track of last write time
|
||||
lastUsed = PIC_Ticks;
|
||||
//Maybe only enable with a keyon?
|
||||
if ( !chan->enabled ) {
|
||||
chan->Enable(true);
|
||||
if ( !mixerChan->enabled ) {
|
||||
mixerChan->Enable(true);
|
||||
}
|
||||
if ( port&1 ) {
|
||||
switch ( mode ) {
|
||||
|
@ -641,121 +639,165 @@ void Module::Init( Mode m ) {
|
|||
}
|
||||
}
|
||||
|
||||
Module::Module() {
|
||||
reg.dual[0] = 0;
|
||||
reg.dual[1] = 0;
|
||||
reg.normal = 0;
|
||||
}
|
||||
}; //namespace
|
||||
|
||||
|
||||
}; //Adlib Namespace
|
||||
|
||||
|
||||
static Adlib::Module module;
|
||||
|
||||
static Adlib::Module* module = 0;
|
||||
|
||||
static void OPL_CallBack(Bitu len) {
|
||||
module.handler->Generate( module.chan, len );
|
||||
module->handler->Generate( module->mixerChan, len );
|
||||
//Disable the sound generation after 30 seconds of silence
|
||||
if ((PIC_Ticks-module.lastUsed) > 30000) {
|
||||
module.chan->Enable(false);
|
||||
if ((PIC_Ticks - module->lastUsed) > 30000) {
|
||||
module->mixerChan->Enable(false);
|
||||
}
|
||||
}
|
||||
|
||||
static Bitu OPL_Read(Bitu port,Bitu iolen) {
|
||||
return module.PortRead( port, iolen );
|
||||
return module->PortRead( port, iolen );
|
||||
}
|
||||
|
||||
void OPL_Write(Bitu port,Bitu val,Bitu iolen) {
|
||||
module.PortWrite( port, val, iolen );
|
||||
module->PortWrite( port, val, iolen );
|
||||
}
|
||||
|
||||
/*
|
||||
Save the current state of the operators as instruments in an reality adlib tracker file
|
||||
*/
|
||||
static void SaveRad() {
|
||||
char b[16 * 1024];
|
||||
int w = 0;
|
||||
|
||||
FILE* handle = OpenCaptureFile("RAD Capture",".rad");
|
||||
if ( !handle )
|
||||
return;
|
||||
//Header
|
||||
fwrite( "RAD by REALiTY!!", 1, 16, handle );
|
||||
b[w++] = 0x10; //version
|
||||
b[w++] = 0x06; //default speed and no description
|
||||
//Write 18 instuments for all operators in the cache
|
||||
for ( int i = 0; i < 18; i++ ) {
|
||||
Bit8u* set = module->cache + ( i / 9 ) * 256;
|
||||
Bitu offset = ((i % 9) / 3) * 8 + (i % 3);
|
||||
Bit8u* base = set + offset;
|
||||
b[w++] = 1 + i; //instrument number
|
||||
b[w++] = base[0x23];
|
||||
b[w++] = base[0x20];
|
||||
b[w++] = base[0x43];
|
||||
b[w++] = base[0x40];
|
||||
b[w++] = base[0x63];
|
||||
b[w++] = base[0x60];
|
||||
b[w++] = base[0x83];
|
||||
b[w++] = base[0x80];
|
||||
b[w++] = set[0xc0 + (i % 9)];
|
||||
b[w++] = base[0xe3];
|
||||
b[w++] = base[0xe0];
|
||||
}
|
||||
b[w++] = 0; //instrument 0, no more instruments following
|
||||
b[w++] = 1; //1 pattern following
|
||||
//Zero out the remaing part of the file a bit to make rad happy
|
||||
for ( int i = 0; i < 64; i++ ) {
|
||||
b[w++] = 0;
|
||||
}
|
||||
fwrite( b, 1, w, handle );
|
||||
fclose( handle );
|
||||
};
|
||||
|
||||
|
||||
static void OPL_SaveRawEvent(bool pressed) {
|
||||
if (!pressed)
|
||||
return;
|
||||
// SaveRad();return;
|
||||
/* Check for previously opened wave file */
|
||||
if ( module.capture ) {
|
||||
delete module.capture;
|
||||
module.capture = 0;
|
||||
if ( module->capture ) {
|
||||
delete module->capture;
|
||||
module->capture = 0;
|
||||
LOG_MSG("Stopped Raw OPL capturing.");
|
||||
} else {
|
||||
LOG_MSG("Preparing to capture Raw OPL, will start with first note played.");
|
||||
module.capture = new Adlib::Capture( &module.cache );
|
||||
module->capture = new Adlib::Capture( &module->cache );
|
||||
}
|
||||
}
|
||||
|
||||
class OPL: public Module_base {
|
||||
private:
|
||||
IO_ReadHandleObject ReadHandler[3];
|
||||
IO_WriteHandleObject WriteHandler[3];
|
||||
MixerObject MixerChan;
|
||||
public:
|
||||
static OPL_Mode oplmode;
|
||||
namespace Adlib {
|
||||
|
||||
OPL(Section* configuration):Module_base(configuration) {
|
||||
Section_prop * section=static_cast<Section_prop *>(configuration);
|
||||
Bitu base = section->Get_hex("sbbase");
|
||||
Bitu rate = section->Get_int("oplrate");
|
||||
std::string oplemu( section->Get_string( "oplemu" ) );
|
||||
Module::Module( Section* configuration ) : Module_base(configuration) {
|
||||
reg.dual[0] = 0;
|
||||
reg.dual[1] = 0;
|
||||
reg.normal = 0;
|
||||
handler = 0;
|
||||
capture = 0;
|
||||
|
||||
module.chan = MixerChan.Install(OPL_CallBack,rate,"FM");
|
||||
if (oplemu == "old") {
|
||||
if ( oplmode == OPL_opl2 ) {
|
||||
module.handler = new old_OPL2::Handler();
|
||||
} else {
|
||||
module.handler = new old_OPL3::Handler();
|
||||
}
|
||||
Section_prop * section=static_cast<Section_prop *>(configuration);
|
||||
Bitu base = section->Get_hex("sbbase");
|
||||
Bitu rate = section->Get_int("oplrate");
|
||||
std::string oplemu( section->Get_string( "oplemu" ) );
|
||||
|
||||
mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM");
|
||||
if (oplemu == "old") {
|
||||
if ( oplmode == OPL_opl2 ) {
|
||||
handler = new old_OPL2::Handler();
|
||||
} else {
|
||||
if ( oplmode == OPL_opl2 ) {
|
||||
module.handler = new OPL2::Handler();
|
||||
} else {
|
||||
module.handler = new OPL3::Handler();
|
||||
}
|
||||
handler = new old_OPL3::Handler();
|
||||
}
|
||||
module.handler->Init( rate );
|
||||
Bit8u portRange = 4; //opl2 will set this to 2
|
||||
switch ( oplmode ) {
|
||||
case OPL_opl2:
|
||||
portRange = 2;
|
||||
module.Init( Adlib::MODE_OPL2 );
|
||||
break;
|
||||
case OPL_dualopl2:
|
||||
module.Init( Adlib::MODE_DUALOPL2 );
|
||||
break;
|
||||
case OPL_opl3:
|
||||
module.Init( Adlib::MODE_OPL3 );
|
||||
break;
|
||||
} else if (oplemu == "fast") {
|
||||
handler = new DBOPL::Handler();
|
||||
} else {
|
||||
if ( oplmode == OPL_opl2 ) {
|
||||
handler = new OPL2::Handler();
|
||||
} else {
|
||||
handler = new OPL3::Handler();
|
||||
}
|
||||
//0x388 range
|
||||
WriteHandler[0].Install(0x388,OPL_Write,IO_MB, portRange );
|
||||
ReadHandler[0].Install(0x388,OPL_Read,IO_MB, portRange - 1 );
|
||||
//0x220 range
|
||||
WriteHandler[1].Install(base,OPL_Write,IO_MB, portRange );
|
||||
ReadHandler[1].Install(base,OPL_Read,IO_MB, portRange - 1 );
|
||||
//0x228 range
|
||||
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");
|
||||
}
|
||||
~OPL() {
|
||||
if ( module.capture )
|
||||
delete module.capture;
|
||||
old_OPL2::YM3812Shutdown();
|
||||
old_OPL3::YMF262Shutdown();
|
||||
handler->Init( rate );
|
||||
Bit8u portRange = 4; //opl2 will set this to 2
|
||||
switch ( oplmode ) {
|
||||
case OPL_opl2:
|
||||
portRange = 2;
|
||||
Init( Adlib::MODE_OPL2 );
|
||||
break;
|
||||
case OPL_dualopl2:
|
||||
Init( Adlib::MODE_DUALOPL2 );
|
||||
break;
|
||||
case OPL_opl3:
|
||||
Init( Adlib::MODE_OPL3 );
|
||||
break;
|
||||
}
|
||||
};
|
||||
//0x388 range
|
||||
WriteHandler[0].Install(0x388,OPL_Write,IO_MB, portRange );
|
||||
ReadHandler[0].Install(0x388,OPL_Read,IO_MB, portRange - 1 );
|
||||
//0x220 range
|
||||
WriteHandler[1].Install(base,OPL_Write,IO_MB, portRange );
|
||||
ReadHandler[1].Install(base,OPL_Read,IO_MB, portRange - 1 );
|
||||
//0x228 range
|
||||
WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2);
|
||||
ReadHandler[2].Install(base+8,OPL_Read,IO_MB,1);
|
||||
|
||||
static OPL* test;
|
||||
MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL");
|
||||
}
|
||||
|
||||
Module::~Module() {
|
||||
if ( capture ) {
|
||||
delete capture;
|
||||
}
|
||||
if ( handler ) {
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
|
||||
//Initialize static members
|
||||
OPL_Mode OPL::oplmode=OPL_none;
|
||||
OPL_Mode Module::oplmode=OPL_none;
|
||||
|
||||
}; //Adlib Namespace
|
||||
|
||||
|
||||
void OPL_Init(Section* sec,OPL_Mode oplmode) {
|
||||
OPL::oplmode = oplmode;
|
||||
test = new OPL(sec);
|
||||
Adlib::Module::oplmode = oplmode;
|
||||
module = new Adlib::Module( sec );
|
||||
}
|
||||
|
||||
void OPL_ShutDown(Section* sec){
|
||||
delete test;
|
||||
delete module;
|
||||
module = 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -16,14 +16,19 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: adlib.h,v 1.2 2009-04-06 11:23:21 qbix79 Exp $ */
|
||||
/* $Id: adlib.h,v 1.3 2009-04-25 09:55:50 harekiet Exp $ */
|
||||
|
||||
#ifndef DOSBOX_ADLIB_H
|
||||
#define DOSBOX_ADLIB_H
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "mixer.h"
|
||||
#include "inout.h"
|
||||
#include "mixer.h"
|
||||
#include "setup.h"
|
||||
#include "pic.h"
|
||||
#include "hardware.h"
|
||||
|
||||
|
||||
namespace Adlib {
|
||||
|
||||
|
@ -108,7 +113,11 @@ typedef Bit8u RegisterCache[512];
|
|||
//Internal class used for dro capturing
|
||||
class Capture;
|
||||
|
||||
class Module {
|
||||
class Module: public Module_base {
|
||||
IO_ReadHandleObject ReadHandler[3];
|
||||
IO_WriteHandleObject WriteHandler[3];
|
||||
MixerObject mixerObject;
|
||||
|
||||
//Mode we're running in
|
||||
Mode mode;
|
||||
//Last selected address in the chip for the different modes
|
||||
|
@ -119,7 +128,8 @@ class Module {
|
|||
void CacheWrite( Bit32u reg, Bit8u val );
|
||||
void DualWrite( Bit8u index, Bit8u reg, Bit8u val );
|
||||
public:
|
||||
MixerChannel* chan;
|
||||
static OPL_Mode oplmode;
|
||||
MixerChannel* mixerChan;
|
||||
Bit32u lastUsed; //Ticks when adlib was last used to turn of mixing after a few second
|
||||
|
||||
Handler* handler; //Handler that will generate the sound
|
||||
|
@ -132,7 +142,8 @@ public:
|
|||
Bitu PortRead( Bitu port, Bitu iolen );
|
||||
void Init( Mode m );
|
||||
|
||||
Module();
|
||||
Module( Section* configuration);
|
||||
~Module();
|
||||
};
|
||||
|
||||
|
||||
|
|
1467
src/hardware/dbopl.cpp
Normal file
1467
src/hardware/dbopl.cpp
Normal file
File diff suppressed because it is too large
Load diff
250
src/hardware/dbopl.h
Normal file
250
src/hardware/dbopl.h
Normal file
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "adlib.h"
|
||||
#include "dosbox.h"
|
||||
|
||||
//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume
|
||||
#define WAVE_HANDLER 10
|
||||
//Use a logarithmic wavetable with an exponential table for volume
|
||||
#define WAVE_TABLELOG 11
|
||||
//Use a linear wavetable with a multiply table for volume
|
||||
#define WAVE_TABLEMUL 12
|
||||
|
||||
//Select the type of wave generator routine
|
||||
#define DBOPL_WAVE WAVE_HANDLER
|
||||
//Enable vibrato in the output
|
||||
#define DBOPL_VIBRATO
|
||||
//Enable tremolo in the output
|
||||
#define DBOPL_TREMOLO
|
||||
|
||||
namespace DBOPL {
|
||||
|
||||
struct Chip;
|
||||
struct Operator;
|
||||
struct Channel;
|
||||
|
||||
#if (DBOPL_WAVE == WAVE_HANDLER)
|
||||
typedef Bits ( FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
|
||||
#endif
|
||||
|
||||
typedef Bits ( DBOPL::Operator::*VolumeHandler) ( );
|
||||
typedef Channel* ( DBOPL::Channel::*SynthHandler) ( );
|
||||
|
||||
//Different synth modes that can generate blocks of data
|
||||
typedef enum {
|
||||
smNone,
|
||||
sm2AM,
|
||||
sm2FM,
|
||||
sm2Rhytm,
|
||||
sm3AM,
|
||||
sm3FM,
|
||||
sm3FMFM,
|
||||
sm3AMFM,
|
||||
sm3FMAM,
|
||||
sm3AMAM,
|
||||
sm3Rhytm,
|
||||
} SynthMode;
|
||||
|
||||
//Shifts for the values contained in chandata variable
|
||||
enum {
|
||||
SHIFT_KSLBASE = 16,
|
||||
SHIFT_KEYCODE = 24,
|
||||
};
|
||||
|
||||
struct Operator {
|
||||
public:
|
||||
//Masks for operator 20 values
|
||||
enum {
|
||||
MASK_KSR = 0x10,
|
||||
MASK_SUSTAIN = 0x20,
|
||||
MASK_VIBRATO = 0x40,
|
||||
MASK_TREMOLO = 0x80,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
OFF,
|
||||
RELEASE,
|
||||
SUSTAIN,
|
||||
DECAY,
|
||||
ATTACK,
|
||||
} State;
|
||||
|
||||
VolumeHandler volHandler;
|
||||
|
||||
#if (DBOPL_WAVE == WAVE_HANDLER)
|
||||
WaveHandler waveHandler; //Routine that generate a wave
|
||||
#else
|
||||
Bit16s* waveBase;
|
||||
Bit32u waveMask;
|
||||
Bit32u waveStart;
|
||||
#endif
|
||||
Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
|
||||
Bit32u waveAdd;
|
||||
|
||||
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
|
||||
|
||||
Bit32u attackAdd; //Timers for the different states of the envelope
|
||||
Bit32u decayAdd;
|
||||
Bit32u releaseAdd;
|
||||
Bit32u rateIndex; //Current position of the evenlope
|
||||
|
||||
Bit8u rateZero; //Bits for the different states of the envelope having no changes
|
||||
Bit8u keyOn; //Bitmask of different values that can generate keyon
|
||||
//Registers, also used to check for changes
|
||||
Bit8u reg20, reg40, reg60, reg80, regE0;
|
||||
//Active part of the envelope we're in
|
||||
Bit8u state;
|
||||
//0xff when tremolo is enabled
|
||||
Bit8u tremoloMask;
|
||||
//Strength of the vibrato
|
||||
Bit8u vibStrength;
|
||||
//Keep track of the calculated KSR so we can check for changes
|
||||
Bit8u ksr;
|
||||
|
||||
private:
|
||||
void SetState( Bit8u s );
|
||||
void UpdateAttack( const Chip* chip );
|
||||
void UpdateRelease( const Chip* chip );
|
||||
void UpdateDecay( const Chip* chip );
|
||||
public:
|
||||
//is the operator silent?
|
||||
void UpdateAttenuation();
|
||||
void UpdateRates( const Chip* chip );
|
||||
void UpdateFrequency( );
|
||||
|
||||
void Write20( const Chip* chip, Bit8u val );
|
||||
void Write40( const Chip* chip, Bit8u val );
|
||||
void Write60( const Chip* chip, Bit8u val );
|
||||
void Write80( const Chip* chip, Bit8u val );
|
||||
void WriteE0( const Chip* chip, Bit8u val );
|
||||
|
||||
bool Silent() const;
|
||||
void KeyOn( Bit8u mask);
|
||||
void KeyOff( Bit8u mask);
|
||||
|
||||
template< State state>
|
||||
Bits TemplateVolume( );
|
||||
|
||||
Bit32s RateForward( Bit32u add );
|
||||
Bitu ForwardWave();
|
||||
Bitu ForwardVolume();
|
||||
|
||||
Bits GetSample( Bits modulation );
|
||||
Bits GetWave( Bitu index, Bitu vol );
|
||||
public:
|
||||
Operator();
|
||||
};
|
||||
|
||||
struct Channel {
|
||||
Operator op[2];
|
||||
inline Operator* Op( Bitu index ) {
|
||||
return &( ( this + (index >> 1) )->op[ index & 1 ]);
|
||||
}
|
||||
SynthHandler synthHandler;
|
||||
Bit32u chanData; //Frequency/octave and derived values
|
||||
Bit32s old[2]; //Old data for feedback
|
||||
|
||||
Bit8u feedback; //Feedback shift
|
||||
Bit8u regB0; //Register values to check for changes
|
||||
Bit8u regC0;
|
||||
//This should correspond with reg104, bit 6 indicates a rhytm channel, bit 7 indicates a silent channel
|
||||
Bit8u fourMask;
|
||||
Bit8s maskLeft; //Sign extended values for both channel's panning
|
||||
Bit8s maskRight;
|
||||
|
||||
//Forward the channel data to the operators of the 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 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 >
|
||||
void GenerateRhytm( Bit32s* output );
|
||||
|
||||
//Generate blocks of data in specific modes
|
||||
template<SynthMode mode>
|
||||
Channel* BlockTemplate( );
|
||||
void BlockRhytm( );
|
||||
Channel();
|
||||
};
|
||||
|
||||
struct Chip {
|
||||
//This is used as the base counter for vibrato and tremolo
|
||||
Bit32u tremoloCounter;
|
||||
Bit32u tremoloAdd;
|
||||
Bit32u vibratoCounter;
|
||||
Bit32u vibratoAdd;
|
||||
|
||||
//Frequency scales for the different multiplications
|
||||
Bit32u freqMul[16];
|
||||
//Rates for decay and release for rate of this chip
|
||||
Bit32u linearRates[76];
|
||||
//Best match attack rates for the rate of this chip
|
||||
Bit32u attackRates[76];
|
||||
|
||||
//18 channels with 2 operators each
|
||||
Channel chan[18];
|
||||
|
||||
Bit8u reg104;
|
||||
Bit8u reg08;
|
||||
Bit8u reg04;
|
||||
Bit8u regBD;
|
||||
Bit8u vibratoShift;
|
||||
Bit8u tremoloShift;
|
||||
//Mask for allowed wave forms
|
||||
Bit8u waveFormMask;
|
||||
//0 or -1 when enabled
|
||||
Bit8s opl3Active;
|
||||
|
||||
Bit8u ForwardTremolo();
|
||||
Bit8s ForwardVibrato();
|
||||
|
||||
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 Generate( Bit32u samples );
|
||||
void Setup( Bit32u r );
|
||||
|
||||
Chip();
|
||||
};
|
||||
|
||||
struct Handler : public Adlib::Handler {
|
||||
DBOPL::Chip chip;
|
||||
virtual Bit32u WriteAddr( Bit32u port, Bit8u val );
|
||||
virtual void WriteReg( Bit32u addr, Bit8u val );
|
||||
virtual void Generate( MixerChannel* chan, Bitu samples );
|
||||
virtual void Init( Bitu rate );
|
||||
};
|
||||
|
||||
|
||||
}; //Namespace
|
Loading…
Add table
Reference in a new issue