]> git.proxmox.com Git - mirror_qemu.git/blobdiff - hw/audio/fmopl.c
i386: Add x-force-features option for testing
[mirror_qemu.git] / hw / audio / fmopl.c
index adcef2d3b90a0549153e877143a14cf73b0557b2..9f50a89b4a888962092e2f4daf8754eeff08e6a8 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#define HAS_YM3812     1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
+#include "qemu/osdep.h"
 #include <math.h>
 //#include "driver.h"          /* use M.A.M.E. */
 #include "fmopl.h"
-
 #ifndef PI
 #define PI 3.14159265358979323846
 #endif
 
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#endif
-
 /* -------------------- for debug --------------------- */
 /* #define OPL_OUTPUT_LOG */
 #ifdef OPL_OUTPUT_LOG
@@ -127,7 +117,7 @@ static const int slot_array[32]=
 /* key scale level */
 /* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
 #define DV (EG_STEP/2)
-static const UINT32 KSL_TABLE[8*16]=
+static const uint32_t KSL_TABLE[8*16]=
 {
        /* OCT 0 */
         0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
@@ -175,7 +165,7 @@ static const UINT32 KSL_TABLE[8*16]=
 /* sustain lebel table (3db per step) */
 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
 #define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
-static const INT32 SL_TABLE[16]={
+static const int32_t SL_TABLE[16]={
  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
 };
@@ -185,22 +175,22 @@ static const INT32 SL_TABLE[16]={
 /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
 /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
-static INT32 *TL_TABLE;
+static int32_t *TL_TABLE;
 
 /* pointers to TL_TABLE with sinwave output offset */
-static INT32 **SIN_TABLE;
+static int32_t **SIN_TABLE;
 
 /* LFO table */
-static INT32 *AMS_TABLE;
-static INT32 *VIB_TABLE;
+static int32_t *AMS_TABLE;
+static int32_t *VIB_TABLE;
 
 /* envelope output curve table */
 /* attack + decay + OFF */
-static INT32 ENV_CURVE[2*EG_ENT+1];
+static int32_t ENV_CURVE[2*EG_ENT+1];
 
 /* multiple table */
 #define ML 2
-static const UINT32 MUL_TABLE[16]= {
+static const uint32_t MUL_TABLE[16]= {
 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
    0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
    8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
@@ -208,7 +198,7 @@ static const UINT32 MUL_TABLE[16]= {
 #undef ML
 
 /* dummy attack / decay rate ( when rate == 0 ) */
-static INT32 RATE_0[16]=
+static int32_t RATE_0[16]=
 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
 /* -------------------- static state --------------------- */
@@ -224,14 +214,14 @@ static OPL_CH *S_CH;
 static OPL_CH *E_CH;
 static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
 
-static INT32 outd[1];
-static INT32 ams;
-static INT32 vib;
-static INT32 *ams_table;
-static INT32 *vib_table;
-static INT32 amsIncr;
-static INT32 vibIncr;
-static INT32 feedback2;                /* connect for SLOT 2 */
+static int32_t outd[1];
+static int32_t ams;
+static int32_t vib;
+static int32_t *ams_table;
+static int32_t *vib_table;
+static int32_t amsIncr;
+static int32_t vibIncr;
+static int32_t feedback2;              /* connect for SLOT 2 */
 
 /* log output level */
 #define LOG_ERR  3      /* ERROR       */
@@ -265,8 +255,6 @@ static inline void OPL_STATUS_SET(FM_OPL *OPL,int flag)
                if(OPL->status & OPL->statusmask)
                {       /* IRQ on */
                        OPL->status |= 0x80;
-                       /* callback user interrupt handler (IRQ is OFF to ON) */
-                       if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
                }
        }
 }
@@ -281,8 +269,6 @@ static inline void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
                if (!(OPL->status & OPL->statusmask) )
                {
                        OPL->status &= 0x7f;
-                       /* callback user interrupt handler (IRQ is ON to OFF) */
-                       if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
                }
        }
 }
@@ -324,7 +310,7 @@ static inline void OPL_KEYOFF(OPL_SLOT *SLOT)
 
 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
 /* return : envelope output */
-static inline UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
+static inline uint32_t OPL_CALC_SLOT( OPL_SLOT *SLOT )
 {
        /* calcrate envelope generator */
        if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
@@ -364,7 +350,7 @@ static inline UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
 /* set algorithm connection */
 static void set_algorithm( OPL_CH *CH)
 {
-       INT32 *carrier = &outd[0];
+       int32_t *carrier = &outd[0];
        CH->connect1 = CH->CON ? carrier : &feedback2;
        CH->connect2 = carrier;
 }
@@ -456,7 +442,7 @@ static inline void set_sl_rr(FM_OPL *OPL,int slot,int v)
 /* ---------- calcrate one of channel ---------- */
 static inline void OPL_CALC_CH( OPL_CH *CH )
 {
-       UINT32 env_out;
+       uint32_t env_out;
        OPL_SLOT *SLOT;
 
        feedback2 = 0;
@@ -501,9 +487,9 @@ static inline void OPL_CALC_CH( OPL_CH *CH )
 #define WHITE_NOISE_db 6.0
 static inline void OPL_CALC_RH( OPL_CH *CH )
 {
-       UINT32 env_tam,env_sd,env_top,env_hh;
+       uint32_t env_tam,env_sd,env_top,env_hh;
        int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
-       INT32 tone8;
+       int32_t tone8;
 
        OPL_SLOT *SLOT;
        int env_out;
@@ -621,20 +607,20 @@ static int OPLOpenTable( void )
        double pom;
 
        /* allocate dynamic tables */
-       if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
+       if( (TL_TABLE = malloc(TL_MAX*2*sizeof(int32_t))) == NULL)
                return 0;
-       if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
+       if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(int32_t *))) == NULL)
        {
                free(TL_TABLE);
                return 0;
        }
-       if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
+       if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(int32_t))) == NULL)
        {
                free(TL_TABLE);
                free(SIN_TABLE);
                return 0;
        }
-       if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
+       if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(int32_t))) == NULL)
        {
                free(TL_TABLE);
                free(SIN_TABLE);
@@ -766,18 +752,15 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v)
                {
                case 0x01:
                        /* wave selector enable */
-                       if(OPL->type&OPL_TYPE_WAVESEL)
+                       OPL->wavesel = v&0x20;
+                        if(!OPL->wavesel)
                        {
-                               OPL->wavesel = v&0x20;
-                               if(!OPL->wavesel)
+                               /* preset compatible mode */
+                               int c;
+                               for(c=0;c<OPL->max_ch;c++)
                                {
-                                       /* preset compatible mode */
-                                       int c;
-                                       for(c=0;c<OPL->max_ch;c++)
-                                       {
-                                               OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
-                                               OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
-                                       }
+                                       OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
+                                       OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
                                }
                        }
                        return;
@@ -794,8 +777,8 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v)
                        }
                        else
                        {       /* set IRQ mask ,timer enable*/
-                               UINT8 st1 = v&1;
-                               UINT8 st2 = (v>>1)&1;
+                               uint8_t st1 = v&1;
+                               uint8_t st2 = (v>>1)&1;
                                /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
                                OPL_STATUS_RESET(OPL,v&0x78);
                                OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
@@ -804,68 +787,21 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v)
                                {
                                        double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
                                        OPL->st[1] = st2;
-                                       if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
+                    if (OPL->TimerHandler) {
+                        (OPL->TimerHandler)(OPL->TimerParam, 1, interval);
+                    }
                                }
                                /* timer 1 */
                                if(OPL->st[0] != st1)
                                {
                                        double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
                                        OPL->st[0] = st1;
-                                       if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
+                    if (OPL->TimerHandler) {
+                        (OPL->TimerHandler)(OPL->TimerParam, 0, interval);
+                    }
                                }
                        }
                        return;
-#if BUILD_Y8950
-               case 0x06:              /* Key Board OUT */
-                       if(OPL->type&OPL_TYPE_KEYBOARD)
-                       {
-                               if(OPL->keyboardhandler_w)
-                                       OPL->keyboardhandler_w(OPL->keyboard_param,v);
-                               else
-                                       LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
-                       }
-                       return;
-               case 0x07:      /* DELTA-T control : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
-                       if(OPL->type&OPL_TYPE_ADPCM)
-                               YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
-                       return;
-               case 0x08:      /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
-                       OPL->mode = v;
-                       v&=0x1f;        /* for DELTA-T unit */
-               case 0x09:              /* START ADD */
-               case 0x0a:
-               case 0x0b:              /* STOP ADD  */
-               case 0x0c:
-               case 0x0d:              /* PRESCALE   */
-               case 0x0e:
-               case 0x0f:              /* ADPCM data */
-               case 0x10:              /* DELTA-N    */
-               case 0x11:              /* DELTA-N    */
-               case 0x12:              /* EG-CTRL    */
-                       if(OPL->type&OPL_TYPE_ADPCM)
-                               YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
-                       return;
-#if 0
-               case 0x15:              /* DAC data    */
-               case 0x16:
-               case 0x17:              /* SHIFT    */
-                       return;
-               case 0x18:              /* I/O CTRL (Direction) */
-                       if(OPL->type&OPL_TYPE_IO)
-                               OPL->portDirection = v&0x0f;
-                       return;
-               case 0x19:              /* I/O DATA */
-                       if(OPL->type&OPL_TYPE_IO)
-                       {
-                               OPL->portLatch = v;
-                               if(OPL->porthandler_w)
-                                       OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
-                       }
-                       return;
-               case 0x1a:              /* PCM data */
-                       return;
-#endif
-#endif
                }
                break;
        case 0x20:      /* am,vib,ksr,eg type,mul */
@@ -894,7 +830,7 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v)
                case 0xbd:
                        /* amsep,vibdep,r,bd,sd,tom,tc,hh */
                        {
-                       UINT8 rkey = OPL->rhythm^v;
+                       uint8_t rkey = OPL->rhythm^v;
                        OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
                        OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
                        OPL->rhythm  = v&0x3f;
@@ -1035,20 +971,19 @@ static void OPL_UnLockTable(void)
        OPLCloseTable();
 }
 
-#if (BUILD_YM3812 || BUILD_YM3526)
 /*******************************************************************************/
 /*             YM3812 local section                                                   */
 /*******************************************************************************/
 
 /* ---------- update one of chip ----------- */
-void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
+void YM3812UpdateOne(FM_OPL *OPL, int16_t *buffer, int length)
 {
     int i;
        int data;
-       OPLSAMPLE *buf = buffer;
-       UINT32 amsCnt  = OPL->amsCnt;
-       UINT32 vibCnt  = OPL->vibCnt;
-       UINT8 rhythm = OPL->rhythm&0x20;
+       int16_t *buf = buffer;
+       uint32_t amsCnt  = OPL->amsCnt;
+       uint32_t  vibCnt  = OPL->vibCnt;
+       uint8_t rhythm = OPL->rhythm&0x20;
        OPL_CH *CH,*R_CH;
 
        if( (void *)OPL != cur_chip ){
@@ -1098,72 +1033,9 @@ void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
        }
 #endif
 }
-#endif /* (BUILD_YM3812 || BUILD_YM3526) */
-
-#if BUILD_Y8950
-
-void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
-{
-    int i;
-       int data;
-       OPLSAMPLE *buf = buffer;
-       UINT32 amsCnt  = OPL->amsCnt;
-       UINT32 vibCnt  = OPL->vibCnt;
-       UINT8 rhythm = OPL->rhythm&0x20;
-       OPL_CH *CH,*R_CH;
-       YM_DELTAT *DELTAT = OPL->deltat;
-
-       /* setup DELTA-T unit */
-       YM_DELTAT_DECODE_PRESET(DELTAT);
-
-       if( (void *)OPL != cur_chip ){
-               cur_chip = (void *)OPL;
-               /* channel pointers */
-               S_CH = OPL->P_CH;
-               E_CH = &S_CH[9];
-               /* rhythm slot */
-               SLOT7_1 = &S_CH[7].SLOT[SLOT1];
-               SLOT7_2 = &S_CH[7].SLOT[SLOT2];
-               SLOT8_1 = &S_CH[8].SLOT[SLOT1];
-               SLOT8_2 = &S_CH[8].SLOT[SLOT2];
-               /* LFO state */
-               amsIncr = OPL->amsIncr;
-               vibIncr = OPL->vibIncr;
-               ams_table = OPL->ams_table;
-               vib_table = OPL->vib_table;
-       }
-       R_CH = rhythm ? &S_CH[6] : E_CH;
-    for( i=0; i < length ; i++ )
-       {
-               /*            channel A         channel B         channel C      */
-               /* LFO */
-               ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
-               vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
-               outd[0] = 0;
-               /* deltaT ADPCM */
-               if( DELTAT->portstate )
-                       YM_DELTAT_ADPCM_CALC(DELTAT);
-               /* FM part */
-               for(CH=S_CH ; CH < R_CH ; CH++)
-                       OPL_CALC_CH(CH);
-               /* Rythn part */
-               if(rhythm)
-                       OPL_CALC_RH(S_CH);
-               /* limit check */
-               data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
-               /* store to sound buffer */
-               buf[i] = data >> OPL_OUTSB;
-       }
-       OPL->amsCnt = amsCnt;
-       OPL->vibCnt = vibCnt;
-       /* deltaT START flag */
-       if( !DELTAT->portstate )
-               OPL->status &= 0xfe;
-}
-#endif
 
 /* ---------- reset one of chip ---------- */
-void OPLResetChip(FM_OPL *OPL)
+static void OPLResetChip(FM_OPL *OPL)
 {
        int c,s;
        int i;
@@ -1177,7 +1049,7 @@ void OPLResetChip(FM_OPL *OPL)
        OPLWriteReg(OPL,0x03,0); /* Timer2 */
        OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
        for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
-       /* reset OPerator paramater */
+       /* reset operator parameter */
        for( c = 0 ; c < OPL->max_ch ; c++ )
        {
                OPL_CH *CH = &OPL->P_CH[c];
@@ -1192,23 +1064,11 @@ void OPLResetChip(FM_OPL *OPL)
                        CH->SLOT[s].evs = 0;
                }
        }
-#if BUILD_Y8950
-       if(OPL->type&OPL_TYPE_ADPCM)
-       {
-               YM_DELTAT *DELTAT = OPL->deltat;
-
-               DELTAT->freqbase = OPL->freqbase;
-               DELTAT->output_pointer = outd;
-               DELTAT->portshift = 5;
-               DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
-               YM_DELTAT_ADPCM_Reset(DELTAT,0);
-       }
-#endif
 }
 
 /* ----------  Create one of vietual YM3812 ----------       */
 /* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
-FM_OPL *OPLCreate(int type, int clock, int rate)
+FM_OPL *OPLCreate(int clock, int rate)
 {
        char *ptr;
        FM_OPL *OPL;
@@ -1219,9 +1079,6 @@ FM_OPL *OPLCreate(int type, int clock, int rate)
        /* allocate OPL state space */
        state_size  = sizeof(FM_OPL);
        state_size += sizeof(OPL_CH)*max_ch;
-#if BUILD_Y8950
-       if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
-#endif
        /* allocate memory block */
        ptr = malloc(state_size);
        if(ptr==NULL) return NULL;
@@ -1229,11 +1086,7 @@ FM_OPL *OPLCreate(int type, int clock, int rate)
        memset(ptr,0,state_size);
        OPL        = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
        OPL->P_CH  = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
-#if BUILD_Y8950
-       if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
-#endif
        /* set channel state pointer */
-       OPL->type  = type;
        OPL->clock = clock;
        OPL->rate  = rate;
        OPL->max_ch = max_ch;
@@ -1278,36 +1131,13 @@ void OPLDestroy(FM_OPL *OPL)
 
 /* ----------  Option handlers ----------       */
 
-void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
+void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,
+                        void *param)
 {
        OPL->TimerHandler   = TimerHandler;
-       OPL->TimerParam = channelOffset;
-}
-void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
-{
-       OPL->IRQHandler     = IRQHandler;
-       OPL->IRQParam = param;
-}
-void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
-{
-       OPL->UpdateHandler = UpdateHandler;
-       OPL->UpdateParam = param;
-}
-#if BUILD_Y8950
-void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
-{
-       OPL->porthandler_w = PortHandler_w;
-       OPL->porthandler_r = PortHandler_r;
-       OPL->port_param = param;
+    OPL->TimerParam = param;
 }
 
-void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
-{
-       OPL->keyboardhandler_w = KeyboardHandler_w;
-       OPL->keyboardhandler_r = KeyboardHandler_r;
-       OPL->keyboard_param = param;
-}
-#endif
 /* ---------- YM3812 I/O interface ---------- */
 int OPLWrite(FM_OPL *OPL,int a,int v)
 {
@@ -1317,7 +1147,6 @@ int OPLWrite(FM_OPL *OPL,int a,int v)
        }
        else
        {       /* data port */
-               if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
 #ifdef OPL_OUTPUT_LOG
        if(opl_dbg_fp)
        {
@@ -1341,28 +1170,12 @@ unsigned char OPLRead(FM_OPL *OPL,int a)
        switch(OPL->address)
        {
        case 0x05: /* KeyBoard IN */
-               if(OPL->type&OPL_TYPE_KEYBOARD)
-               {
-                       if(OPL->keyboardhandler_r)
-                               return OPL->keyboardhandler_r(OPL->keyboard_param);
-                       else {
-                               LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
-                       }
-               }
                return 0;
 #if 0
        case 0x0f: /* ADPCM-DATA  */
                return 0;
 #endif
        case 0x19: /* I/O DATA    */
-               if(OPL->type&OPL_TYPE_IO)
-               {
-                       if(OPL->porthandler_r)
-                               return OPL->porthandler_r(OPL->port_param);
-                       else {
-                               LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
-                       }
-               }
                return 0;
        case 0x1a: /* PCM-DATA    */
                return 0;
@@ -1383,12 +1196,14 @@ int OPLTimerOver(FM_OPL *OPL,int c)
                if( OPL->mode & 0x80 )
                {       /* CSM mode total level latch and auto key on */
                        int ch;
-                       if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
                        for(ch=0;ch<9;ch++)
                                CSMKeyControll( &OPL->P_CH[ch] );
                }
        }
        /* reload timer */
-       if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
+    if (OPL->TimerHandler) {
+        (OPL->TimerHandler)(OPL->TimerParam, c,
+                            (double)OPL->T[c] * OPL->TimerBase);
+    }
        return OPL->status>>7;
 }