symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/fmopl.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2 **
       
     3 ** File: fmopl.c -- software implementation of FM sound generator
       
     4 **
       
     5 ** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
       
     6 **
       
     7 ** Version 0.37a
       
     8 **
       
     9 */
       
    10 
       
    11 /*
       
    12 	preliminary :
       
    13 	Problem :
       
    14 	note:
       
    15 */
       
    16 
       
    17 /* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL.
       
    18  *
       
    19  * This library is free software; you can redistribute it and/or
       
    20  * modify it under the terms of the GNU Lesser General Public
       
    21  * License as published by the Free Software Foundation; either
       
    22  * version 2.1 of the License, or (at your option) any later version.
       
    23  *
       
    24  * This library is distributed in the hope that it will be useful,
       
    25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    27  * Lesser General Public License for more details.
       
    28  *
       
    29  * You should have received a copy of the GNU Lesser General Public
       
    30  * License along with this library; if not, write to the Free Software
       
    31  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    32  */
       
    33 
       
    34 #define INLINE		__inline
       
    35 #define HAS_YM3812	1
       
    36 
       
    37 #include <stdio.h>
       
    38 #include <stdlib.h>
       
    39 #include <string.h>
       
    40 #include <stdarg.h>
       
    41 #include <math.h>
       
    42 //#include "driver.h"		/* use M.A.M.E. */
       
    43 #include "fmopl.h"
       
    44 
       
    45 #ifndef PI
       
    46 #define PI 3.14159265358979323846
       
    47 #endif
       
    48 
       
    49 /* -------------------- for debug --------------------- */
       
    50 /* #define OPL_OUTPUT_LOG */
       
    51 #ifdef OPL_OUTPUT_LOG
       
    52 static FILE *opl_dbg_fp = NULL;
       
    53 static FM_OPL *opl_dbg_opl[16];
       
    54 static int opl_dbg_maxchip,opl_dbg_chip;
       
    55 #endif
       
    56 
       
    57 /* -------------------- preliminary define section --------------------- */
       
    58 /* attack/decay rate time rate */
       
    59 #define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
       
    60 #define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
       
    61 
       
    62 #define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
       
    63 
       
    64 #define FREQ_BITS 24			/* frequency turn          */
       
    65 
       
    66 /* counter bits = 20 , octerve 7 */
       
    67 #define FREQ_RATE   (1<<(FREQ_BITS-20))
       
    68 #define TL_BITS    (FREQ_BITS+2)
       
    69 
       
    70 /* final output shift , limit minimum and maximum */
       
    71 #define OPL_OUTSB   (TL_BITS+3-16)		/* OPL output final shift 16bit */
       
    72 #define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
       
    73 #define OPL_MINOUT (-0x8000<<OPL_OUTSB)
       
    74 
       
    75 /* -------------------- quality selection --------------------- */
       
    76 
       
    77 /* sinwave entries */
       
    78 /* used static memory = SIN_ENT * 4 (byte) */
       
    79 #define SIN_ENT 2048
       
    80 
       
    81 /* output level entries (envelope,sinwave) */
       
    82 /* envelope counter lower bits */
       
    83 #define ENV_BITS 16
       
    84 /* envelope output entries */
       
    85 #define EG_ENT   4096
       
    86 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
       
    87 /* used static  memory = EG_ENT*4 (byte)                     */
       
    88 
       
    89 #define EG_OFF   ((2*EG_ENT)<<ENV_BITS)  /* OFF          */
       
    90 #define EG_DED   EG_OFF
       
    91 #define EG_DST   (EG_ENT<<ENV_BITS)      /* DECAY  START */
       
    92 #define EG_AED   EG_DST
       
    93 #define EG_AST   0                       /* ATTACK START */
       
    94 
       
    95 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
       
    96 
       
    97 /* LFO table entries */
       
    98 #define VIB_ENT 512
       
    99 #define VIB_SHIFT (32-9)
       
   100 #define AMS_ENT 512
       
   101 #define AMS_SHIFT (32-9)
       
   102 
       
   103 #define VIB_RATE 256
       
   104 
       
   105 /* -------------------- local defines , macros --------------------- */
       
   106 
       
   107 /* register number to channel number , slot offset */
       
   108 #define SLOT1 0
       
   109 #define SLOT2 1
       
   110 
       
   111 /* envelope phase */
       
   112 #define ENV_MOD_RR  0x00
       
   113 #define ENV_MOD_DR  0x01
       
   114 #define ENV_MOD_AR  0x02
       
   115 
       
   116 /* -------------------- tables --------------------- */
       
   117 static const int slot_array[32]=
       
   118 {
       
   119 	 0, 2, 4, 1, 3, 5,-1,-1,
       
   120 	 6, 8,10, 7, 9,11,-1,-1,
       
   121 	12,14,16,13,15,17,-1,-1,
       
   122 	-1,-1,-1,-1,-1,-1,-1,-1
       
   123 };
       
   124 
       
   125 /* key scale level */
       
   126 /* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
       
   127 #define DV (EG_STEP/2)
       
   128 static const UINT32 KSL_TABLE[8*16]=
       
   129 {
       
   130 	/* OCT 0 */
       
   131 	 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
       
   132 	 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
       
   133 	 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
       
   134 	 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
       
   135 	/* OCT 1 */
       
   136 	 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
       
   137 	 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
       
   138 	 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
       
   139 	 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
       
   140 	/* OCT 2 */
       
   141 	 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
       
   142 	 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
       
   143 	 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
       
   144 	 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
       
   145 	/* OCT 3 */
       
   146 	 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
       
   147 	 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
       
   148 	 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
       
   149 	 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
       
   150 	/* OCT 4 */
       
   151 	 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
       
   152 	 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
       
   153 	 9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
       
   154 	10.875/DV,11.250/DV,11.625/DV,12.000/DV,
       
   155 	/* OCT 5 */
       
   156 	 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
       
   157 	 9.000/DV,10.125/DV,10.875/DV,11.625/DV,
       
   158 	12.000/DV,12.750/DV,13.125/DV,13.500/DV,
       
   159 	13.875/DV,14.250/DV,14.625/DV,15.000/DV,
       
   160 	/* OCT 6 */
       
   161 	 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
       
   162 	12.000/DV,13.125/DV,13.875/DV,14.625/DV,
       
   163 	15.000/DV,15.750/DV,16.125/DV,16.500/DV,
       
   164 	16.875/DV,17.250/DV,17.625/DV,18.000/DV,
       
   165 	/* OCT 7 */
       
   166 	 0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
       
   167 	15.000/DV,16.125/DV,16.875/DV,17.625/DV,
       
   168 	18.000/DV,18.750/DV,19.125/DV,19.500/DV,
       
   169 	19.875/DV,20.250/DV,20.625/DV,21.000/DV
       
   170 };
       
   171 #undef DV
       
   172 
       
   173 /* sustain lebel table (3db per step) */
       
   174 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
       
   175 #define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
       
   176 static const INT32 SL_TABLE[16]={
       
   177  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
       
   178  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
       
   179 };
       
   180 #undef SC
       
   181 
       
   182 #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
       
   183 /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
       
   184 /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
       
   185 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
       
   186 static INT32 *TL_TABLE;
       
   187 
       
   188 /* pointers to TL_TABLE with sinwave output offset */
       
   189 static INT32 **SIN_TABLE;
       
   190 
       
   191 /* LFO table */
       
   192 static INT32 *AMS_TABLE;
       
   193 static INT32 *VIB_TABLE;
       
   194 
       
   195 /* envelope output curve table */
       
   196 /* attack + decay + OFF */
       
   197 static INT32 ENV_CURVE[2*EG_ENT+1];
       
   198 
       
   199 /* multiple table */
       
   200 #define ML 2
       
   201 static const UINT32 MUL_TABLE[16]= {
       
   202 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
       
   203    0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
       
   204    8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
       
   205 };
       
   206 #undef ML
       
   207 
       
   208 /* dummy attack / decay rate ( when rate == 0 ) */
       
   209 static INT32 RATE_0[16]=
       
   210 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
       
   211 
       
   212 /* -------------------- static state --------------------- */
       
   213 
       
   214 /* lock level of common table */
       
   215 static int num_lock = 0;
       
   216 
       
   217 /* work table */
       
   218 static void *cur_chip = NULL;	/* current chip point */
       
   219 /* currenct chip state */
       
   220 /* static OPLSAMPLE  *bufL,*bufR; */
       
   221 static OPL_CH *S_CH;
       
   222 static OPL_CH *E_CH;
       
   223 OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
       
   224 
       
   225 static INT32 outd[1];
       
   226 static INT32 ams;
       
   227 static INT32 vib;
       
   228 INT32  *ams_table;
       
   229 INT32  *vib_table;
       
   230 static INT32 amsIncr;
       
   231 static INT32 vibIncr;
       
   232 static INT32 feedback2;		/* connect for SLOT 2 */
       
   233 
       
   234 /* log output level */
       
   235 #define LOG_ERR  3      /* ERROR       */
       
   236 #define LOG_WAR  2      /* WARNING     */
       
   237 #define LOG_INF  1      /* INFORMATION */
       
   238 
       
   239 //#define LOG_LEVEL LOG_INF
       
   240 #define LOG_LEVEL	LOG_ERR
       
   241 
       
   242 //#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
       
   243 #define LOG(n,x)
       
   244 
       
   245 /* --------------------- subroutines  --------------------- */
       
   246 
       
   247 INLINE int Limit( int val, int max, int min ) {
       
   248 	if ( val > max )
       
   249 		val = max;
       
   250 	else if ( val < min )
       
   251 		val = min;
       
   252 
       
   253 	return val;
       
   254 }
       
   255 
       
   256 /* status set and IRQ handling */
       
   257 INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
       
   258 {
       
   259 	/* set status flag */
       
   260 	OPL->status |= flag;
       
   261 	if(!(OPL->status & 0x80))
       
   262 	{
       
   263 		if(OPL->status & OPL->statusmask)
       
   264 		{	/* IRQ on */
       
   265 			OPL->status |= 0x80;
       
   266 			/* callback user interrupt handler (IRQ is OFF to ON) */
       
   267 			if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
       
   268 		}
       
   269 	}
       
   270 }
       
   271 
       
   272 /* status reset and IRQ handling */
       
   273 INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
       
   274 {
       
   275 	/* reset status flag */
       
   276 	OPL->status &=~flag;
       
   277 	if((OPL->status & 0x80))
       
   278 	{
       
   279 		if (!(OPL->status & OPL->statusmask) )
       
   280 		{
       
   281 			OPL->status &= 0x7f;
       
   282 			/* callback user interrupt handler (IRQ is ON to OFF) */
       
   283 			if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
       
   284 		}
       
   285 	}
       
   286 }
       
   287 
       
   288 /* IRQ mask set */
       
   289 INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
       
   290 {
       
   291 	OPL->statusmask = flag;
       
   292 	/* IRQ handling check */
       
   293 	OPL_STATUS_SET(OPL,0);
       
   294 	OPL_STATUS_RESET(OPL,0);
       
   295 }
       
   296 
       
   297 /* ----- key on  ----- */
       
   298 INLINE void OPL_KEYON(OPL_SLOT *SLOT)
       
   299 {
       
   300 	/* sin wave restart */
       
   301 	SLOT->Cnt = 0;
       
   302 	/* set attack */
       
   303 	SLOT->evm = ENV_MOD_AR;
       
   304 	SLOT->evs = SLOT->evsa;
       
   305 	SLOT->evc = EG_AST;
       
   306 	SLOT->eve = EG_AED;
       
   307 }
       
   308 /* ----- key off ----- */
       
   309 INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
       
   310 {
       
   311 	if( SLOT->evm > ENV_MOD_RR)
       
   312 	{
       
   313 		/* set envelope counter from envleope output */
       
   314 		SLOT->evm = ENV_MOD_RR;
       
   315 		if( !(SLOT->evc&EG_DST) )
       
   316 			//SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
       
   317 			SLOT->evc = EG_DST;
       
   318 		SLOT->eve = EG_DED;
       
   319 		SLOT->evs = SLOT->evsr;
       
   320 	}
       
   321 }
       
   322 
       
   323 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
       
   324 /* return : envelope output */
       
   325 INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
       
   326 {
       
   327 	/* calcrate envelope generator */
       
   328 	if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
       
   329 	{
       
   330 		switch( SLOT->evm ){
       
   331 		case ENV_MOD_AR: /* ATTACK -> DECAY1 */
       
   332 			/* next DR */
       
   333 			SLOT->evm = ENV_MOD_DR;
       
   334 			SLOT->evc = EG_DST;
       
   335 			SLOT->eve = SLOT->SL;
       
   336 			SLOT->evs = SLOT->evsd;
       
   337 			break;
       
   338 		case ENV_MOD_DR: /* DECAY -> SL or RR */
       
   339 			SLOT->evc = SLOT->SL;
       
   340 			SLOT->eve = EG_DED;
       
   341 			if(SLOT->eg_typ)
       
   342 			{
       
   343 				SLOT->evs = 0;
       
   344 			}
       
   345 			else
       
   346 			{
       
   347 				SLOT->evm = ENV_MOD_RR;
       
   348 				SLOT->evs = SLOT->evsr;
       
   349 			}
       
   350 			break;
       
   351 		case ENV_MOD_RR: /* RR -> OFF */
       
   352 			SLOT->evc = EG_OFF;
       
   353 			SLOT->eve = EG_OFF+1;
       
   354 			SLOT->evs = 0;
       
   355 			break;
       
   356 		}
       
   357 	}
       
   358 	/* calcrate envelope */
       
   359 	return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
       
   360 }
       
   361 
       
   362 /* set algorythm connection */
       
   363 static void set_algorythm( OPL_CH *CH)
       
   364 {
       
   365 	INT32 *carrier = &outd[0];
       
   366 	CH->connect1 = CH->CON ? carrier : &feedback2;
       
   367 	CH->connect2 = carrier;
       
   368 }
       
   369 
       
   370 /* ---------- frequency counter for operater update ---------- */
       
   371 INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
       
   372 {
       
   373 	int ksr;
       
   374 
       
   375 	/* frequency step counter */
       
   376 	SLOT->Incr = CH->fc * SLOT->mul;
       
   377 	ksr = CH->kcode >> SLOT->KSR;
       
   378 
       
   379 	if( SLOT->ksr != ksr )
       
   380 	{
       
   381 		SLOT->ksr = ksr;
       
   382 		/* attack , decay rate recalcration */
       
   383 		SLOT->evsa = SLOT->AR[ksr];
       
   384 		SLOT->evsd = SLOT->DR[ksr];
       
   385 		SLOT->evsr = SLOT->RR[ksr];
       
   386 	}
       
   387 	SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
       
   388 }
       
   389 
       
   390 /* set multi,am,vib,EG-TYP,KSR,mul */
       
   391 INLINE void set_mul(FM_OPL *OPL,int slot,int v)
       
   392 {
       
   393 	OPL_CH   *CH   = &OPL->P_CH[slot/2];
       
   394 	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
       
   395 
       
   396 	SLOT->mul    = MUL_TABLE[v&0x0f];
       
   397 	SLOT->KSR    = (v&0x10) ? 0 : 2;
       
   398 	SLOT->eg_typ = (v&0x20)>>5;
       
   399 	SLOT->vib    = (v&0x40);
       
   400 	SLOT->ams    = (v&0x80);
       
   401 	CALC_FCSLOT(CH,SLOT);
       
   402 }
       
   403 
       
   404 /* set ksl & tl */
       
   405 INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
       
   406 {
       
   407 	OPL_CH   *CH   = &OPL->P_CH[slot/2];
       
   408 	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
       
   409 	int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
       
   410 
       
   411 	SLOT->ksl = ksl ? 3-ksl : 31;
       
   412 	SLOT->TL  = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
       
   413 
       
   414 	if( !(OPL->mode&0x80) )
       
   415 	{	/* not CSM latch total level */
       
   416 		SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
       
   417 	}
       
   418 }
       
   419 
       
   420 /* set attack rate & decay rate  */
       
   421 INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
       
   422 {
       
   423 	OPL_CH   *CH   = &OPL->P_CH[slot/2];
       
   424 	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
       
   425 	int ar = v>>4;
       
   426 	int dr = v&0x0f;
       
   427 
       
   428 	SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
       
   429 	SLOT->evsa = SLOT->AR[SLOT->ksr];
       
   430 	if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
       
   431 
       
   432 	SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
       
   433 	SLOT->evsd = SLOT->DR[SLOT->ksr];
       
   434 	if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
       
   435 }
       
   436 
       
   437 /* set sustain level & release rate */
       
   438 INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
       
   439 {
       
   440 	OPL_CH   *CH   = &OPL->P_CH[slot/2];
       
   441 	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
       
   442 	int sl = v>>4;
       
   443 	int rr = v & 0x0f;
       
   444 
       
   445 	SLOT->SL = SL_TABLE[sl];
       
   446 	if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
       
   447 	SLOT->RR = &OPL->DR_TABLE[rr<<2];
       
   448 	SLOT->evsr = SLOT->RR[SLOT->ksr];
       
   449 	if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
       
   450 }
       
   451 
       
   452 /* operator output calcrator */
       
   453 #define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
       
   454 /* ---------- calcrate one of channel ---------- */
       
   455 INLINE void OPL_CALC_CH( OPL_CH *CH )
       
   456 {
       
   457 	UINT32 env_out;
       
   458 	OPL_SLOT *SLOT;
       
   459 
       
   460 	feedback2 = 0;
       
   461 	/* SLOT 1 */
       
   462 	SLOT = &CH->SLOT[SLOT1];
       
   463 	env_out=OPL_CALC_SLOT(SLOT);
       
   464 	if( env_out < EG_ENT-1 )
       
   465 	{
       
   466 		/* PG */
       
   467 		if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
       
   468 		else          SLOT->Cnt += SLOT->Incr;
       
   469 		/* connectoion */
       
   470 		if(CH->FB)
       
   471 		{
       
   472 			int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
       
   473 			CH->op1_out[1] = CH->op1_out[0];
       
   474 			*CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
       
   475 		}
       
   476 		else
       
   477 		{
       
   478 			*CH->connect1 += OP_OUT(SLOT,env_out,0);
       
   479 		}
       
   480 	}else
       
   481 	{
       
   482 		CH->op1_out[1] = CH->op1_out[0];
       
   483 		CH->op1_out[0] = 0;
       
   484 	}
       
   485 	/* SLOT 2 */
       
   486 	SLOT = &CH->SLOT[SLOT2];
       
   487 	env_out=OPL_CALC_SLOT(SLOT);
       
   488 	if( env_out < EG_ENT-1 )
       
   489 	{
       
   490 		/* PG */
       
   491 		if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
       
   492 		else          SLOT->Cnt += SLOT->Incr;
       
   493 		/* connectoion */
       
   494 		outd[0] += OP_OUT(SLOT,env_out, feedback2);
       
   495 	}
       
   496 }
       
   497 
       
   498 /* ---------- calcrate rythm block ---------- */
       
   499 #define WHITE_NOISE_db 6.0
       
   500 INLINE void OPL_CALC_RH( OPL_CH *CH )
       
   501 {
       
   502 	UINT32 env_tam,env_sd,env_top,env_hh;
       
   503 	int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
       
   504 	INT32 tone8;
       
   505 
       
   506 	OPL_SLOT *SLOT;
       
   507 	int env_out;
       
   508 
       
   509 	/* BD : same as FM serial mode and output level is large */
       
   510 	feedback2 = 0;
       
   511 	/* SLOT 1 */
       
   512 	SLOT = &CH[6].SLOT[SLOT1];
       
   513 	env_out=OPL_CALC_SLOT(SLOT);
       
   514 	if( env_out < EG_ENT-1 )
       
   515 	{
       
   516 		/* PG */
       
   517 		if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
       
   518 		else          SLOT->Cnt += SLOT->Incr;
       
   519 		/* connectoion */
       
   520 		if(CH[6].FB)
       
   521 		{
       
   522 			int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
       
   523 			CH[6].op1_out[1] = CH[6].op1_out[0];
       
   524 			feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
       
   525 		}
       
   526 		else
       
   527 		{
       
   528 			feedback2 = OP_OUT(SLOT,env_out,0);
       
   529 		}
       
   530 	}else
       
   531 	{
       
   532 		feedback2 = 0;
       
   533 		CH[6].op1_out[1] = CH[6].op1_out[0];
       
   534 		CH[6].op1_out[0] = 0;
       
   535 	}
       
   536 	/* SLOT 2 */
       
   537 	SLOT = &CH[6].SLOT[SLOT2];
       
   538 	env_out=OPL_CALC_SLOT(SLOT);
       
   539 	if( env_out < EG_ENT-1 )
       
   540 	{
       
   541 		/* PG */
       
   542 		if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
       
   543 		else          SLOT->Cnt += SLOT->Incr;
       
   544 		/* connectoion */
       
   545 		outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
       
   546 	}
       
   547 
       
   548 	// SD  (17) = mul14[fnum7] + white noise
       
   549 	// TAM (15) = mul15[fnum8]
       
   550 	// TOP (18) = fnum6(mul18[fnum8]+whitenoise)
       
   551 	// HH  (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
       
   552 	env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
       
   553 	env_tam=OPL_CALC_SLOT(SLOT8_1);
       
   554 	env_top=OPL_CALC_SLOT(SLOT8_2);
       
   555 	env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
       
   556 
       
   557 	/* PG */
       
   558 	if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
       
   559 	else             SLOT7_1->Cnt += 2*SLOT7_1->Incr;
       
   560 	if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
       
   561 	else             SLOT7_2->Cnt += (CH[7].fc*8);
       
   562 	if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
       
   563 	else             SLOT8_1->Cnt += SLOT8_1->Incr;
       
   564 	if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
       
   565 	else             SLOT8_2->Cnt += (CH[8].fc*48);
       
   566 
       
   567 	tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
       
   568 
       
   569 	/* SD */
       
   570 	if( env_sd < EG_ENT-1 )
       
   571 		outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
       
   572 	/* TAM */
       
   573 	if( env_tam < EG_ENT-1 )
       
   574 		outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
       
   575 	/* TOP-CY */
       
   576 	if( env_top < EG_ENT-1 )
       
   577 		outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
       
   578 	/* HH */
       
   579 	if( env_hh  < EG_ENT-1 )
       
   580 		outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
       
   581 }
       
   582 
       
   583 /* ----------- initialize time tabls ----------- */
       
   584 static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
       
   585 {
       
   586 	int i;
       
   587 	double rate;
       
   588 
       
   589 	/* make attack rate & decay rate tables */
       
   590 	for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
       
   591 	for (i = 4;i <= 60;i++){
       
   592 		rate  = OPL->freqbase;						/* frequency rate */
       
   593 		if( i < 60 ) rate *= 1.0+(i&3)*0.25;		/* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
       
   594 		rate *= 1<<((i>>2)-1);						/* b2-5 : shift bit */
       
   595 		rate *= (double)(EG_ENT<<ENV_BITS);
       
   596 		OPL->AR_TABLE[i] = rate / ARRATE;
       
   597 		OPL->DR_TABLE[i] = rate / DRRATE;
       
   598 	}
       
   599 	for (i = 60;i < 76;i++)
       
   600 	{
       
   601 		OPL->AR_TABLE[i] = EG_AED-1;
       
   602 		OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
       
   603 	}
       
   604 #if 0
       
   605 	for (i = 0;i < 64 ;i++){	/* make for overflow area */
       
   606 		LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
       
   607 			((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
       
   608 			((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
       
   609 	}
       
   610 #endif
       
   611 }
       
   612 
       
   613 /* ---------- generic table initialize ---------- */
       
   614 static int OPLOpenTable( void )
       
   615 {
       
   616 	int s,t;
       
   617 	double rate;
       
   618 	int i,j;
       
   619 	double pom;
       
   620 
       
   621 	/* allocate dynamic tables */
       
   622 	if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
       
   623 		return 0;
       
   624 	if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
       
   625 	{
       
   626 		free(TL_TABLE);
       
   627 		return 0;
       
   628 	}
       
   629 	if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
       
   630 	{
       
   631 		free(TL_TABLE);
       
   632 		free(SIN_TABLE);
       
   633 		return 0;
       
   634 	}
       
   635 	if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
       
   636 	{
       
   637 		free(TL_TABLE);
       
   638 		free(SIN_TABLE);
       
   639 		free(AMS_TABLE);
       
   640 		return 0;
       
   641 	}
       
   642 	/* make total level table */
       
   643 	for (t = 0;t < EG_ENT-1 ;t++){
       
   644 		rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20);	/* dB -> voltage */
       
   645 		TL_TABLE[       t] =  (int)rate;
       
   646 		TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
       
   647 /*		LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
       
   648 	}
       
   649 	/* fill volume off area */
       
   650 	for ( t = EG_ENT-1; t < TL_MAX ;t++){
       
   651 		TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
       
   652 	}
       
   653 
       
   654 	/* make sinwave table (total level offet) */
       
   655 	/* degree 0 = degree 180                   = off */
       
   656 	SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2]         = &TL_TABLE[EG_ENT-1];
       
   657 	for (s = 1;s <= SIN_ENT/4;s++){
       
   658 		pom = sin(2*PI*s/SIN_ENT); /* sin     */
       
   659 		pom = 20*log10(1/pom);	   /* decibel */
       
   660 		j = pom / EG_STEP;         /* TL_TABLE steps */
       
   661 
       
   662         /* degree 0   -  90    , degree 180 -  90 : plus section */
       
   663 		SIN_TABLE[          s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
       
   664         /* degree 180 - 270    , degree 360 - 270 : minus section */
       
   665 		SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT  -s] = &TL_TABLE[TL_MAX+j];
       
   666 /*		LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
       
   667 	}
       
   668 	for (s = 0;s < SIN_ENT;s++)
       
   669 	{
       
   670 		SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
       
   671 		SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
       
   672 		SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
       
   673 	}
       
   674 
       
   675 	/* envelope counter -> envelope output table */
       
   676 	for (i=0; i<EG_ENT; i++)
       
   677 	{
       
   678 		/* ATTACK curve */
       
   679 		pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
       
   680 		/* if( pom >= EG_ENT ) pom = EG_ENT-1; */
       
   681 		ENV_CURVE[i] = (int)pom;
       
   682 		/* DECAY ,RELEASE curve */
       
   683 		ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
       
   684 	}
       
   685 	/* off */
       
   686 	ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
       
   687 	/* make LFO ams table */
       
   688 	for (i=0; i<AMS_ENT; i++)
       
   689 	{
       
   690 		pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
       
   691 		AMS_TABLE[i]         = (1.0/EG_STEP)*pom; /* 1dB   */
       
   692 		AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
       
   693 	}
       
   694 	/* make LFO vibrate table */
       
   695 	for (i=0; i<VIB_ENT; i++)
       
   696 	{
       
   697 		/* 100cent = 1seminote = 6% ?? */
       
   698 		pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
       
   699 		VIB_TABLE[i]         = VIB_RATE + (pom*0.07); /* +- 7cent */
       
   700 		VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
       
   701 		/* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */
       
   702 	}
       
   703 	return 1;
       
   704 }
       
   705 
       
   706 
       
   707 static void OPLCloseTable( void )
       
   708 {
       
   709 	free(TL_TABLE);
       
   710 	free(SIN_TABLE);
       
   711 	free(AMS_TABLE);
       
   712 	free(VIB_TABLE);
       
   713 }
       
   714 
       
   715 /* CSM Key Controll */
       
   716 INLINE void CSMKeyControll(OPL_CH *CH)
       
   717 {
       
   718 	OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
       
   719 	OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
       
   720 	/* all key off */
       
   721 	OPL_KEYOFF(slot1);
       
   722 	OPL_KEYOFF(slot2);
       
   723 	/* total level latch */
       
   724 	slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
       
   725 	slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
       
   726 	/* key on */
       
   727 	CH->op1_out[0] = CH->op1_out[1] = 0;
       
   728 	OPL_KEYON(slot1);
       
   729 	OPL_KEYON(slot2);
       
   730 }
       
   731 
       
   732 /* ---------- opl initialize ---------- */
       
   733 static void OPL_initalize(FM_OPL *OPL)
       
   734 {
       
   735 	int fn;
       
   736 
       
   737 	/* frequency base */
       
   738 	OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72  : 0;
       
   739 	/* Timer base time */
       
   740 	OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
       
   741 	/* make time tables */
       
   742 	init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
       
   743 	/* make fnumber -> increment counter table */
       
   744 	for( fn=0 ; fn < 1024 ; fn++ )
       
   745 	{
       
   746 		OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
       
   747 	}
       
   748 	/* LFO freq.table */
       
   749 	OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
       
   750 	OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
       
   751 }
       
   752 
       
   753 /* ---------- write a OPL registers ---------- */
       
   754 static void OPLWriteReg(FM_OPL *OPL, int r, int v)
       
   755 {
       
   756 	OPL_CH *CH;
       
   757 	int slot;
       
   758 	int block_fnum;
       
   759 
       
   760 	switch(r&0xe0)
       
   761 	{
       
   762 	case 0x00: /* 00-1f:controll */
       
   763 		switch(r&0x1f)
       
   764 		{
       
   765 		case 0x01:
       
   766 			/* wave selector enable */
       
   767 			if(OPL->type&OPL_TYPE_WAVESEL)
       
   768 			{
       
   769 				OPL->wavesel = v&0x20;
       
   770 				if(!OPL->wavesel)
       
   771 				{
       
   772 					/* preset compatible mode */
       
   773 					int c;
       
   774 					for(c=0;c<OPL->max_ch;c++)
       
   775 					{
       
   776 						OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
       
   777 						OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
       
   778 					}
       
   779 				}
       
   780 			}
       
   781 			return;
       
   782 		case 0x02:	/* Timer 1 */
       
   783 			OPL->T[0] = (256-v)*4;
       
   784 			break;
       
   785 		case 0x03:	/* Timer 2 */
       
   786 			OPL->T[1] = (256-v)*16;
       
   787 			return;
       
   788 		case 0x04:	/* IRQ clear / mask and Timer enable */
       
   789 			if(v&0x80)
       
   790 			{	/* IRQ flag clear */
       
   791 				OPL_STATUS_RESET(OPL,0x7f);
       
   792 			}
       
   793 			else
       
   794 			{	/* set IRQ mask ,timer enable*/
       
   795 				UINT8 st1 = v&1;
       
   796 				UINT8 st2 = (v>>1)&1;
       
   797 				/* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
       
   798 				OPL_STATUS_RESET(OPL,v&0x78);
       
   799 				OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
       
   800 				/* timer 2 */
       
   801 				if(OPL->st[1] != st2)
       
   802 				{
       
   803 					double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
       
   804 					OPL->st[1] = st2;
       
   805 					if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
       
   806 				}
       
   807 				/* timer 1 */
       
   808 				if(OPL->st[0] != st1)
       
   809 				{
       
   810 					double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
       
   811 					OPL->st[0] = st1;
       
   812 					if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
       
   813 				}
       
   814 			}
       
   815 			return;
       
   816 #if BUILD_Y8950
       
   817 		case 0x06:		/* Key Board OUT */
       
   818 			if(OPL->type&OPL_TYPE_KEYBOARD)
       
   819 			{
       
   820 				if(OPL->keyboardhandler_w)
       
   821 					OPL->keyboardhandler_w(OPL->keyboard_param,v);
       
   822 				else
       
   823 					LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
       
   824 			}
       
   825 			return;
       
   826 		case 0x07:	/* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
       
   827 			if(OPL->type&OPL_TYPE_ADPCM)
       
   828 				YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
       
   829 			return;
       
   830 		case 0x08:	/* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
       
   831 			OPL->mode = v;
       
   832 			v&=0x1f;	/* for DELTA-T unit */
       
   833 		case 0x09:		/* START ADD */
       
   834 		case 0x0a:
       
   835 		case 0x0b:		/* STOP ADD  */
       
   836 		case 0x0c:
       
   837 		case 0x0d:		/* PRESCALE   */
       
   838 		case 0x0e:
       
   839 		case 0x0f:		/* ADPCM data */
       
   840 		case 0x10: 		/* DELTA-N    */
       
   841 		case 0x11: 		/* DELTA-N    */
       
   842 		case 0x12: 		/* EG-CTRL    */
       
   843 			if(OPL->type&OPL_TYPE_ADPCM)
       
   844 				YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
       
   845 			return;
       
   846 #if 0
       
   847 		case 0x15:		/* DAC data    */
       
   848 		case 0x16:
       
   849 		case 0x17:		/* SHIFT    */
       
   850 			return;
       
   851 		case 0x18:		/* I/O CTRL (Direction) */
       
   852 			if(OPL->type&OPL_TYPE_IO)
       
   853 				OPL->portDirection = v&0x0f;
       
   854 			return;
       
   855 		case 0x19:		/* I/O DATA */
       
   856 			if(OPL->type&OPL_TYPE_IO)
       
   857 			{
       
   858 				OPL->portLatch = v;
       
   859 				if(OPL->porthandler_w)
       
   860 					OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
       
   861 			}
       
   862 			return;
       
   863 		case 0x1a:		/* PCM data */
       
   864 			return;
       
   865 #endif
       
   866 #endif
       
   867 		}
       
   868 		break;
       
   869 	case 0x20:	/* am,vib,ksr,eg type,mul */
       
   870 		slot = slot_array[r&0x1f];
       
   871 		if(slot == -1) return;
       
   872 		set_mul(OPL,slot,v);
       
   873 		return;
       
   874 	case 0x40:
       
   875 		slot = slot_array[r&0x1f];
       
   876 		if(slot == -1) return;
       
   877 		set_ksl_tl(OPL,slot,v);
       
   878 		return;
       
   879 	case 0x60:
       
   880 		slot = slot_array[r&0x1f];
       
   881 		if(slot == -1) return;
       
   882 		set_ar_dr(OPL,slot,v);
       
   883 		return;
       
   884 	case 0x80:
       
   885 		slot = slot_array[r&0x1f];
       
   886 		if(slot == -1) return;
       
   887 		set_sl_rr(OPL,slot,v);
       
   888 		return;
       
   889 	case 0xa0:
       
   890 		switch(r)
       
   891 		{
       
   892 		case 0xbd:
       
   893 			/* amsep,vibdep,r,bd,sd,tom,tc,hh */
       
   894 			{
       
   895 			UINT8 rkey = OPL->rythm^v;
       
   896 			OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
       
   897 			OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
       
   898 			OPL->rythm  = v&0x3f;
       
   899 			if(OPL->rythm&0x20)
       
   900 			{
       
   901 #if 0
       
   902 				usrintf_showmessage("OPL Rythm mode select");
       
   903 #endif
       
   904 				/* BD key on/off */
       
   905 				if(rkey&0x10)
       
   906 				{
       
   907 					if(v&0x10)
       
   908 					{
       
   909 						OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
       
   910 						OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
       
   911 						OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
       
   912 					}
       
   913 					else
       
   914 					{
       
   915 						OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
       
   916 						OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
       
   917 					}
       
   918 				}
       
   919 				/* SD key on/off */
       
   920 				if(rkey&0x08)
       
   921 				{
       
   922 					if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
       
   923 					else       OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
       
   924 				}/* TAM key on/off */
       
   925 				if(rkey&0x04)
       
   926 				{
       
   927 					if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
       
   928 					else       OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
       
   929 				}
       
   930 				/* TOP-CY key on/off */
       
   931 				if(rkey&0x02)
       
   932 				{
       
   933 					if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
       
   934 					else       OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
       
   935 				}
       
   936 				/* HH key on/off */
       
   937 				if(rkey&0x01)
       
   938 				{
       
   939 					if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
       
   940 					else       OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
       
   941 				}
       
   942 			}
       
   943 			}
       
   944 			return;
       
   945 		}
       
   946 		/* keyon,block,fnum */
       
   947 		if( (r&0x0f) > 8) return;
       
   948 		CH = &OPL->P_CH[r&0x0f];
       
   949 		if(!(r&0x10))
       
   950 		{	/* a0-a8 */
       
   951 			block_fnum  = (CH->block_fnum&0x1f00) | v;
       
   952 		}
       
   953 		else
       
   954 		{	/* b0-b8 */
       
   955 			int keyon = (v>>5)&1;
       
   956 			block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
       
   957 			if(CH->keyon != keyon)
       
   958 			{
       
   959 				if( (CH->keyon=keyon) )
       
   960 				{
       
   961 					CH->op1_out[0] = CH->op1_out[1] = 0;
       
   962 					OPL_KEYON(&CH->SLOT[SLOT1]);
       
   963 					OPL_KEYON(&CH->SLOT[SLOT2]);
       
   964 				}
       
   965 				else
       
   966 				{
       
   967 					OPL_KEYOFF(&CH->SLOT[SLOT1]);
       
   968 					OPL_KEYOFF(&CH->SLOT[SLOT2]);
       
   969 				}
       
   970 			}
       
   971 		}
       
   972 		/* update */
       
   973 		if(CH->block_fnum != block_fnum)
       
   974 		{
       
   975 			int blockRv = 7-(block_fnum>>10);
       
   976 			int fnum   = block_fnum&0x3ff;
       
   977 			CH->block_fnum = block_fnum;
       
   978 
       
   979 			CH->ksl_base = KSL_TABLE[block_fnum>>6];
       
   980 			CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
       
   981 			CH->kcode = CH->block_fnum>>9;
       
   982 			if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
       
   983 			CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
       
   984 			CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
       
   985 		}
       
   986 		return;
       
   987 	case 0xc0:
       
   988 		/* FB,C */
       
   989 		if( (r&0x0f) > 8) return;
       
   990 		CH = &OPL->P_CH[r&0x0f];
       
   991 		{
       
   992 		int feedback = (v>>1)&7;
       
   993 		CH->FB   = feedback ? (8+1) - feedback : 0;
       
   994 		CH->CON = v&1;
       
   995 		set_algorythm(CH);
       
   996 		}
       
   997 		return;
       
   998 	case 0xe0: /* wave type */
       
   999 		slot = slot_array[r&0x1f];
       
  1000 		if(slot == -1) return;
       
  1001 		CH = &OPL->P_CH[slot/2];
       
  1002 		if(OPL->wavesel)
       
  1003 		{
       
  1004 			/* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
       
  1005 			CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
       
  1006 		}
       
  1007 		return;
       
  1008 	}
       
  1009 }
       
  1010 
       
  1011 /* lock/unlock for common table */
       
  1012 static int OPL_LockTable(void)
       
  1013 {
       
  1014 	num_lock++;
       
  1015 	if(num_lock>1) return 0;
       
  1016 	/* first time */
       
  1017 	cur_chip = NULL;
       
  1018 	/* allocate total level table (128kb space) */
       
  1019 	if( !OPLOpenTable() )
       
  1020 	{
       
  1021 		num_lock--;
       
  1022 		return -1;
       
  1023 	}
       
  1024 	return 0;
       
  1025 }
       
  1026 
       
  1027 static void OPL_UnLockTable(void)
       
  1028 {
       
  1029 	if(num_lock) num_lock--;
       
  1030 	if(num_lock) return;
       
  1031 	/* last time */
       
  1032 	cur_chip = NULL;
       
  1033 	OPLCloseTable();
       
  1034 }
       
  1035 
       
  1036 #if (BUILD_YM3812 || BUILD_YM3526)
       
  1037 /*******************************************************************************/
       
  1038 /*		YM3812 local section                                                   */
       
  1039 /*******************************************************************************/
       
  1040 
       
  1041 /* ---------- update one of chip ----------- */
       
  1042 void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
       
  1043 {
       
  1044     int i;
       
  1045 	int data;
       
  1046 	OPLSAMPLE *buf = buffer;
       
  1047 	UINT32 amsCnt  = OPL->amsCnt;
       
  1048 	UINT32 vibCnt  = OPL->vibCnt;
       
  1049 	UINT8 rythm = OPL->rythm&0x20;
       
  1050 	OPL_CH *CH,*R_CH;
       
  1051 
       
  1052 	if( (void *)OPL != cur_chip ){
       
  1053 		cur_chip = (void *)OPL;
       
  1054 		/* channel pointers */
       
  1055 		S_CH = OPL->P_CH;
       
  1056 		E_CH = &S_CH[9];
       
  1057 		/* rythm slot */
       
  1058 		SLOT7_1 = &S_CH[7].SLOT[SLOT1];
       
  1059 		SLOT7_2 = &S_CH[7].SLOT[SLOT2];
       
  1060 		SLOT8_1 = &S_CH[8].SLOT[SLOT1];
       
  1061 		SLOT8_2 = &S_CH[8].SLOT[SLOT2];
       
  1062 		/* LFO state */
       
  1063 		amsIncr = OPL->amsIncr;
       
  1064 		vibIncr = OPL->vibIncr;
       
  1065 		ams_table = OPL->ams_table;
       
  1066 		vib_table = OPL->vib_table;
       
  1067 	}
       
  1068 	R_CH = rythm ? &S_CH[6] : E_CH;
       
  1069     for( i=0; i < length ; i++ )
       
  1070 	{
       
  1071 		/*            channel A         channel B         channel C      */
       
  1072 		/* LFO */
       
  1073 		ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
       
  1074 		vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
       
  1075 		outd[0] = 0;
       
  1076 		/* FM part */
       
  1077 		for(CH=S_CH ; CH < R_CH ; CH++)
       
  1078 			OPL_CALC_CH(CH);
       
  1079 		/* Rythn part */
       
  1080 		if(rythm)
       
  1081 			OPL_CALC_RH(S_CH);
       
  1082 		/* limit check */
       
  1083 		data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
       
  1084 		/* store to sound buffer */
       
  1085 		buf[i] = data >> OPL_OUTSB;
       
  1086 	}
       
  1087 
       
  1088 	OPL->amsCnt = amsCnt;
       
  1089 	OPL->vibCnt = vibCnt;
       
  1090 #ifdef OPL_OUTPUT_LOG
       
  1091 	if(opl_dbg_fp)
       
  1092 	{
       
  1093 		for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
       
  1094 			if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
       
  1095 		fprintf(opl_dbg_fp,"%c%c%c",0x20+opl_dbg_chip,length&0xff,length/256);
       
  1096 	}
       
  1097 #endif
       
  1098 }
       
  1099 #endif /* (BUILD_YM3812 || BUILD_YM3526) */
       
  1100 
       
  1101 #if BUILD_Y8950
       
  1102 
       
  1103 void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
       
  1104 {
       
  1105     int i;
       
  1106 	int data;
       
  1107 	OPLSAMPLE *buf = buffer;
       
  1108 	UINT32 amsCnt  = OPL->amsCnt;
       
  1109 	UINT32 vibCnt  = OPL->vibCnt;
       
  1110 	UINT8 rythm = OPL->rythm&0x20;
       
  1111 	OPL_CH *CH,*R_CH;
       
  1112 	YM_DELTAT *DELTAT = OPL->deltat;
       
  1113 
       
  1114 	/* setup DELTA-T unit */
       
  1115 	YM_DELTAT_DECODE_PRESET(DELTAT);
       
  1116 
       
  1117 	if( (void *)OPL != cur_chip ){
       
  1118 		cur_chip = (void *)OPL;
       
  1119 		/* channel pointers */
       
  1120 		S_CH = OPL->P_CH;
       
  1121 		E_CH = &S_CH[9];
       
  1122 		/* rythm slot */
       
  1123 		SLOT7_1 = &S_CH[7].SLOT[SLOT1];
       
  1124 		SLOT7_2 = &S_CH[7].SLOT[SLOT2];
       
  1125 		SLOT8_1 = &S_CH[8].SLOT[SLOT1];
       
  1126 		SLOT8_2 = &S_CH[8].SLOT[SLOT2];
       
  1127 		/* LFO state */
       
  1128 		amsIncr = OPL->amsIncr;
       
  1129 		vibIncr = OPL->vibIncr;
       
  1130 		ams_table = OPL->ams_table;
       
  1131 		vib_table = OPL->vib_table;
       
  1132 	}
       
  1133 	R_CH = rythm ? &S_CH[6] : E_CH;
       
  1134     for( i=0; i < length ; i++ )
       
  1135 	{
       
  1136 		/*            channel A         channel B         channel C      */
       
  1137 		/* LFO */
       
  1138 		ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
       
  1139 		vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
       
  1140 		outd[0] = 0;
       
  1141 		/* deltaT ADPCM */
       
  1142 		if( DELTAT->portstate )
       
  1143 			YM_DELTAT_ADPCM_CALC(DELTAT);
       
  1144 		/* FM part */
       
  1145 		for(CH=S_CH ; CH < R_CH ; CH++)
       
  1146 			OPL_CALC_CH(CH);
       
  1147 		/* Rythn part */
       
  1148 		if(rythm)
       
  1149 			OPL_CALC_RH(S_CH);
       
  1150 		/* limit check */
       
  1151 		data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
       
  1152 		/* store to sound buffer */
       
  1153 		buf[i] = data >> OPL_OUTSB;
       
  1154 	}
       
  1155 	OPL->amsCnt = amsCnt;
       
  1156 	OPL->vibCnt = vibCnt;
       
  1157 	/* deltaT START flag */
       
  1158 	if( !DELTAT->portstate )
       
  1159 		OPL->status &= 0xfe;
       
  1160 }
       
  1161 #endif
       
  1162 
       
  1163 /* ---------- reset one of chip ---------- */
       
  1164 void OPLResetChip(FM_OPL *OPL)
       
  1165 {
       
  1166 	int c,s;
       
  1167 	int i;
       
  1168 
       
  1169 	/* reset chip */
       
  1170 	OPL->mode   = 0;	/* normal mode */
       
  1171 	OPL_STATUS_RESET(OPL,0x7f);
       
  1172 	/* reset with register write */
       
  1173 	OPLWriteReg(OPL,0x01,0); /* wabesel disable */
       
  1174 	OPLWriteReg(OPL,0x02,0); /* Timer1 */
       
  1175 	OPLWriteReg(OPL,0x03,0); /* Timer2 */
       
  1176 	OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
       
  1177 	for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
       
  1178 	/* reset OPerator paramater */
       
  1179 	for( c = 0 ; c < OPL->max_ch ; c++ )
       
  1180 	{
       
  1181 		OPL_CH *CH = &OPL->P_CH[c];
       
  1182 		/* OPL->P_CH[c].PAN = OPN_CENTER; */
       
  1183 		for(s = 0 ; s < 2 ; s++ )
       
  1184 		{
       
  1185 			/* wave table */
       
  1186 			CH->SLOT[s].wavetable = &SIN_TABLE[0];
       
  1187 			/* CH->SLOT[s].evm = ENV_MOD_RR; */
       
  1188 			CH->SLOT[s].evc = EG_OFF;
       
  1189 			CH->SLOT[s].eve = EG_OFF+1;
       
  1190 			CH->SLOT[s].evs = 0;
       
  1191 		}
       
  1192 	}
       
  1193 #if BUILD_Y8950
       
  1194 	if(OPL->type&OPL_TYPE_ADPCM)
       
  1195 	{
       
  1196 		YM_DELTAT *DELTAT = OPL->deltat;
       
  1197 
       
  1198 		DELTAT->freqbase = OPL->freqbase;
       
  1199 		DELTAT->output_pointer = outd;
       
  1200 		DELTAT->portshift = 5;
       
  1201 		DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
       
  1202 		YM_DELTAT_ADPCM_Reset(DELTAT,0);
       
  1203 	}
       
  1204 #endif
       
  1205 }
       
  1206 
       
  1207 /* ----------  Create one of vietual YM3812 ----------       */
       
  1208 /* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
       
  1209 FM_OPL *OPLCreate(int type, int clock, int rate)
       
  1210 {
       
  1211 	char *ptr;
       
  1212 	FM_OPL *OPL;
       
  1213 	int state_size;
       
  1214 	int max_ch = 9; /* normaly 9 channels */
       
  1215 
       
  1216 	if( OPL_LockTable() ==-1) return NULL;
       
  1217 	/* allocate OPL state space */
       
  1218 	state_size  = sizeof(FM_OPL);
       
  1219 	state_size += sizeof(OPL_CH)*max_ch;
       
  1220 #if BUILD_Y8950
       
  1221 	if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
       
  1222 #endif
       
  1223 	/* allocate memory block */
       
  1224 	ptr = malloc(state_size);
       
  1225 	if(ptr==NULL) return NULL;
       
  1226 	/* clear */
       
  1227 	memset(ptr,0,state_size);
       
  1228 	OPL        = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
       
  1229 	OPL->P_CH  = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
       
  1230 #if BUILD_Y8950
       
  1231 	if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
       
  1232 #endif
       
  1233 	/* set channel state pointer */
       
  1234 	OPL->type  = type;
       
  1235 	OPL->clock = clock;
       
  1236 	OPL->rate  = rate;
       
  1237 	OPL->max_ch = max_ch;
       
  1238 	/* init grobal tables */
       
  1239 	OPL_initalize(OPL);
       
  1240 	/* reset chip */
       
  1241 	OPLResetChip(OPL);
       
  1242 #ifdef OPL_OUTPUT_LOG
       
  1243 	if(!opl_dbg_fp)
       
  1244 	{
       
  1245 		opl_dbg_fp = fopen("opllog.opl","wb");
       
  1246 		opl_dbg_maxchip = 0;
       
  1247 	}
       
  1248 	if(opl_dbg_fp)
       
  1249 	{
       
  1250 		opl_dbg_opl[opl_dbg_maxchip] = OPL;
       
  1251 		fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip,
       
  1252 			type,
       
  1253 			clock&0xff,
       
  1254 			(clock/0x100)&0xff,
       
  1255 			(clock/0x10000)&0xff,
       
  1256 			(clock/0x1000000)&0xff);
       
  1257 		opl_dbg_maxchip++;
       
  1258 	}
       
  1259 #endif
       
  1260 	return OPL;
       
  1261 }
       
  1262 
       
  1263 /* ----------  Destroy one of vietual YM3812 ----------       */
       
  1264 void OPLDestroy(FM_OPL *OPL)
       
  1265 {
       
  1266 #ifdef OPL_OUTPUT_LOG
       
  1267 	if(opl_dbg_fp)
       
  1268 	{
       
  1269 		fclose(opl_dbg_fp);
       
  1270 		opl_dbg_fp = NULL;
       
  1271 	}
       
  1272 #endif
       
  1273 	OPL_UnLockTable();
       
  1274 	free(OPL);
       
  1275 }
       
  1276 
       
  1277 /* ----------  Option handlers ----------       */
       
  1278 
       
  1279 void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
       
  1280 {
       
  1281 	OPL->TimerHandler   = TimerHandler;
       
  1282 	OPL->TimerParam = channelOffset;
       
  1283 }
       
  1284 void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
       
  1285 {
       
  1286 	OPL->IRQHandler     = IRQHandler;
       
  1287 	OPL->IRQParam = param;
       
  1288 }
       
  1289 void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
       
  1290 {
       
  1291 	OPL->UpdateHandler = UpdateHandler;
       
  1292 	OPL->UpdateParam = param;
       
  1293 }
       
  1294 #if BUILD_Y8950
       
  1295 void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
       
  1296 {
       
  1297 	OPL->porthandler_w = PortHandler_w;
       
  1298 	OPL->porthandler_r = PortHandler_r;
       
  1299 	OPL->port_param = param;
       
  1300 }
       
  1301 
       
  1302 void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
       
  1303 {
       
  1304 	OPL->keyboardhandler_w = KeyboardHandler_w;
       
  1305 	OPL->keyboardhandler_r = KeyboardHandler_r;
       
  1306 	OPL->keyboard_param = param;
       
  1307 }
       
  1308 #endif
       
  1309 /* ---------- YM3812 I/O interface ---------- */
       
  1310 int OPLWrite(FM_OPL *OPL,int a,int v)
       
  1311 {
       
  1312 	if( !(a&1) )
       
  1313 	{	/* address port */
       
  1314 		OPL->address = v & 0xff;
       
  1315 	}
       
  1316 	else
       
  1317 	{	/* data port */
       
  1318 		if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
       
  1319 #ifdef OPL_OUTPUT_LOG
       
  1320 	if(opl_dbg_fp)
       
  1321 	{
       
  1322 		for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
       
  1323 			if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
       
  1324 		fprintf(opl_dbg_fp,"%c%c%c",0x10+opl_dbg_chip,OPL->address,v);
       
  1325 	}
       
  1326 #endif
       
  1327 		OPLWriteReg(OPL,OPL->address,v);
       
  1328 	}
       
  1329 	return OPL->status>>7;
       
  1330 }
       
  1331 
       
  1332 unsigned char OPLRead(FM_OPL *OPL,int a)
       
  1333 {
       
  1334 	if( !(a&1) )
       
  1335 	{	/* status port */
       
  1336 		return OPL->status & (OPL->statusmask|0x80);
       
  1337 	}
       
  1338 	/* data port */
       
  1339 	switch(OPL->address)
       
  1340 	{
       
  1341 	case 0x05: /* KeyBoard IN */
       
  1342 		if(OPL->type&OPL_TYPE_KEYBOARD)
       
  1343 		{
       
  1344 			if(OPL->keyboardhandler_r)
       
  1345 				return OPL->keyboardhandler_r(OPL->keyboard_param);
       
  1346 			else
       
  1347 				LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
       
  1348 		}
       
  1349 		return 0;
       
  1350 #if 0
       
  1351 	case 0x0f: /* ADPCM-DATA  */
       
  1352 		return 0;
       
  1353 #endif
       
  1354 	case 0x19: /* I/O DATA    */
       
  1355 		if(OPL->type&OPL_TYPE_IO)
       
  1356 		{
       
  1357 			if(OPL->porthandler_r)
       
  1358 				return OPL->porthandler_r(OPL->port_param);
       
  1359 			else
       
  1360 				LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
       
  1361 		}
       
  1362 		return 0;
       
  1363 	case 0x1a: /* PCM-DATA    */
       
  1364 		return 0;
       
  1365 	}
       
  1366 	return 0;
       
  1367 }
       
  1368 
       
  1369 int OPLTimerOver(FM_OPL *OPL,int c)
       
  1370 {
       
  1371 	if( c )
       
  1372 	{	/* Timer B */
       
  1373 		OPL_STATUS_SET(OPL,0x20);
       
  1374 	}
       
  1375 	else
       
  1376 	{	/* Timer A */
       
  1377 		OPL_STATUS_SET(OPL,0x40);
       
  1378 		/* CSM mode key,TL controll */
       
  1379 		if( OPL->mode & 0x80 )
       
  1380 		{	/* CSM mode total level latch and auto key on */
       
  1381 			int ch;
       
  1382 			if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
       
  1383 			for(ch=0;ch<9;ch++)
       
  1384 				CSMKeyControll( &OPL->P_CH[ch] );
       
  1385 		}
       
  1386 	}
       
  1387 	/* reload timer */
       
  1388 	if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
       
  1389 	return OPL->status>>7;
       
  1390 }