Annotation of generator/ym2612/fm.c, revision 1.1.1.1

1.1       root        1: #define YM2610B_WARNING
                      2: 
                      3: /* YM2608 rhythm data is PCM ,not an ADPCM */
                      4: #define YM2608_RHYTHM_PCM
                      5: 
                      6: /*
                      7: **
                      8: ** File: fm.c -- software implementation of FM sound generator
                      9: **
                     10: ** Copyright (C) 1998 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
                     11: **
                     12: ** Version 0.35f
                     13: **
                     14: */
                     15: 
                     16: /*
                     17: **** change log. (hiro-shi) ****
                     18: ** 08-12-98:
                     19: ** rename ADPCMA -> ADPCMB, ADPCMB -> ADPCMA
                     20: ** move ROM limit check.(CALC_CH? -> 2610Write1/2)
                     21: ** test program (ADPCMB_TEST)
                     22: ** move ADPCM A/B end check.
                     23: ** ADPCMB repeat flag(no check)
                     24: ** change ADPCM volume rate (8->16) (32->48).
                     25: **
                     26: ** 09-12-98:
                     27: ** change ADPCM volume. (8->16, 48->64)
                     28: ** replace ym2610 ch0/3 (YM-2610B)
                     29: ** init cur_chip (restart bug fix)
                     30: ** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff.
                     31: ** add ADPCM_SHIFT_MASK
                     32: ** change ADPCMA_DECODE_MIN/MAX.
                     33: */
                     34: 
                     35: /*
                     36:     no check:
                     37:         YM2608 rhythm sound
                     38:         OPN  SSG type envelope
                     39:         YM2612 DAC output mode
                     40:         YM2151 CSM speech mode
                     41:     no support:
                     42:         status busy flag (already not busy)
                     43:         LFO contoller (YM2612/YM2610/YM2608/YM2151)
                     44:         YM2151 noise mode
                     45:         YM2608 DELTA-T-ADPCM and RYTHM
                     46:         YM2610 DELTA-T-ADPCM with PCM port
                     47:         YM2610 PCM memory data access
                     48: 
                     49:         YM2608 status mask (register :0x110)
                     50:     preliminary :
                     51:         key scale level rate (?)
                     52:         attack rate time rate , curve (?)
                     53:         decay  rate time rate , curve (?)
                     54:         self feedback calcration
                     55:         YM2610 ADPCM mixing level
                     56:     Problem :
                     57: 
                     58:     note:
                     59:                         OPN                           OPM
                     60:         fnum          fMus * 2^20 / (fM/(12*n))
                     61:         TimerOverA    (12*n)*(1024-NA)/fFM        64*(1024-Na)/fm
                     62:         TimerOverB    (12*n)*(256-NB)/fFM       1024*(256-Nb)/fm
                     63:         output bits   10bit<<3bit               16bit * 2ch (YM3012=10bit<<3bit)
                     64:         sampling rate fFM / (12*6) ?            fFM / 64
                     65:         lfo freq                                ( fM*2^(LFRQ/16) ) / (4295*10^6)
                     66: */
                     67: 
                     68: /************************************************************************/
                     69: /*    comment of hiro-shi(Hiromitsu Shioya)                             */
                     70: /*    YM2610(B) = (OPN-B                                                */
                     71: /*    YM2610  : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch      */
                     72: /*    YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch      */
                     73: /************************************************************************/
                     74: 
                     75: #include <stdio.h>
                     76: #include <stdlib.h>
                     77: #include <string.h>
                     78: #include <stdarg.h>
                     79: #include <math.h>
                     80: 
                     81: /* tidied for Generator by James Ponder, 27th May 1999 */
                     82: 
                     83: #include "support.h"
                     84: #include "fm.h"
                     85: 
                     86: #ifndef PI
                     87: #define PI 3.14159265357989
                     88: #endif
                     89: 
                     90: /***** shared function building option ****/
                     91: #define BUILD_OPN (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2612)
                     92: #define BUILD_OPNB (BUILD_YM2610||BUILD_YM2610B)
                     93: #define BUILD_FM_ADPCMA (BUILD_YM2608||BUILD_YM2610)
                     94: #define BUILD_FM_ADPCMB (BUILD_YM2608||BUILD_YM2610)
                     95: 
                     96: /**** YM2610 ADPCM defines ****/
                     97: #define ADPCMA_VOLUME_RATE  (1)
                     98: #define ADPCMB_VOLUME_RATE  (2) /* DELTA-T volume rate */
                     99: 
                    100: #define ADPCM_SHIFT    (16)
                    101: 
                    102: #define AUDIO_CONV(A) ((A))
                    103: #define AUDIO_CONV16(A) ((A))
                    104: 
                    105: /* ------------------------------------------------------------------ */
                    106: #ifdef __RAINE__
                    107: #define INTERNAL_TIMER          /* use internal timer */
                    108: #endif
                    109: /* -------------------- speed up optimize switch -------------------- */
                    110: /* ---------- Enable ---------- */
                    111: #define TL_SAVE_MEM     /* save some memories for total level */
                    112: /* ---------- Disable ---------- */
                    113: #if 0
                    114: #define SEG_SUPPORT         /* OPN SSG type envelope support   */
                    115: #define LFO_SUPPORT         /* LFO support                     */
                    116: #endif
                    117: /* -------------------- preliminary define section --------------------- */
                    118: /* attack/decay rate time rate */
                    119: #define OPM_ARRATE     399128
                    120: #define OPM_DRRATE    5514396
                    121: /* It is not checked , because I haven't YM2203 rate */
                    122: #define OPN_ARRATE  OPM_ARRATE
                    123: #define OPN_DRRATE  OPM_DRRATE
                    124: 
                    125: #define FREQ_BITS 24            /* frequency turn          */
                    126: 
                    127: /* counter bits = 21 , octerve 7 */
                    128: #define FREQ_RATE   (1<<(FREQ_BITS-21))
                    129: #define TL_BITS    (FREQ_BITS+2)
                    130: 
                    131: /* final output shift , limit minimum and maximum */
                    132: #define OPN_OUTSB   (TL_BITS+2-16)      /* OPN output final shift 16bit */
                    133: #define OPN_MAXOUT (0x7fff<<OPN_OUTSB)
                    134: #define OPN_MINOUT (-0x8000<<OPN_OUTSB)
                    135: 
                    136: #define OPM_OUTSB   (TL_BITS+2-16)      /* OPM output final shift 16bit */
                    137: #define OPM_MAXOUT (0x7fff<<OPM_OUTSB)
                    138: #define OPM_MINOUT (-0x8000<<OPM_OUTSB)
                    139: 
                    140: #define OPNB_OUTSB   (TL_BITS+2-16)     /* OPN output final shift 16bit */
                    141: #define OPNB_MAXOUT (0x7fff<<OPNB_OUTSB)
                    142: #define OPNB_MINOUT (-0x8000<<OPNB_OUTSB)
                    143: 
                    144: /* -------------------- quality selection --------------------- */
                    145: 
                    146: /* sinwave entries */
                    147: /* used static memory = SIN_ENT * 4 (byte) */
                    148: #define SIN_ENT 2048
                    149: 
                    150: /* output level entries (envelope,sinwave) */
                    151: /* envelope counter lower bits */
                    152: #define ENV_BITS 16
                    153: /* envelope output entries */
                    154: #define EG_ENT   4096
                    155: /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
                    156: /* used static  memory = EG_ENT*4 (byte)                     */
                    157: 
                    158: #ifdef SEG_SUPPORT
                    159: #define EG_OFF   ((3*EG_ENT)<<ENV_BITS)  /* OFF          */
                    160: #define EG_UED   EG_OFF
                    161: #define EG_UST   ((2*EG_ENT)<<ENV_BITS)  /* UPSISE START */
                    162: #define EG_DED   EG_UST
                    163: #else
                    164: #define EG_OFF   ((2*EG_ENT)<<ENV_BITS)  /* OFF          */
                    165: #define EG_DED   EG_OFF
                    166: #endif
                    167: #define EG_DST   (EG_ENT<<ENV_BITS)      /* DECAY  START */
                    168: #define EG_AED   EG_DST
                    169: #define EG_AST   0                       /* ATTACK START */
                    170: 
                    171: #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
                    172: 
                    173: /* LFO table entries */
                    174: #define LFO_ENT 512
                    175: 
                    176: /* -------------------- local defines , macros --------------------- */
                    177: /* number of maximum envelope counter */
                    178: /* #define ENV_OFF ((EG_ENT<<ENV_BITS)-1) */
                    179: 
                    180: /* register number to channel number , slot offset */
                    181: #define OPN_CHAN(N) (N&3)
                    182: #define OPN_SLOT(N) ((N>>2)&3)
                    183: #define OPM_CHAN(N) (N&7)
                    184: #define OPM_SLOT(N) ((N>>3)&3)
                    185: /* slot number */
                    186: #define SLOT1 0
                    187: #define SLOT2 2
                    188: #define SLOT3 1
                    189: #define SLOT4 3
                    190: 
                    191: /* envelope phase */
                    192: #define ENV_MOD_OFF 0x00
                    193: #define ENV_MOD_RR  0x01
                    194: #define ENV_MOD_SR  0x02
                    195: #define ENV_MOD_DR  0x03
                    196: #define ENV_MOD_AR  0x04
                    197: #define ENV_SSG_SR  0x05
                    198: #define ENV_SSG_DR  0x06
                    199: #define ENV_SSG_AR  0x07
                    200: 
                    201: /* bit0 = right enable , bit1 = left enable (FOR YM2612) */
                    202: #define OPN_RIGHT  1
                    203: #define OPN_LEFT   2
                    204: #define OPN_CENTER 3
                    205: 
                    206: /* bit0 = left enable , bit1 = right enable */
                    207: #define OPM_LEFT   1
                    208: #define OPM_RIGHT  2
                    209: #define OPM_CENTER 3
                    210: /* */
                    211: 
                    212: /* YM2608 Rhythm Number */
                    213: #define RY_BD  0
                    214: #define RY_SD  1
                    215: #define RY_TOP 2
                    216: #define RY_HH  3
                    217: #define RY_TOM 4
                    218: #define RY_RIM 5
                    219: 
                    220: /* FM timer model */
                    221: #define FM_TIMER_SINGLE (0)
                    222: #define FM_TIMER_INTERVAL (1)
                    223: 
                    224: /* ---------- OPN / OPM one channel  ---------- */
                    225: typedef struct fm_slot {
                    226:     int *DT;                /* detune          :DT_TABLE[DT]       */
                    227:     int DT2;                /* multiple,Detune2:(DT2<<4)|ML for OPM*/
                    228:     int TL;                 /* total level     :TL << 8            */
                    229:     signed int TLL;         /* adjusted now TL                     */
                    230:     unsigned char KSR;      /* key scale rate  :3-KSR              */
                    231:     int *AR;                /* attack rate     :&AR_TABLE[AR<<1]   */
                    232:     int *DR;                /* decay rate      :&DR_TALBE[DR<<1]   */
                    233:     int *SR;                /* sustin rate     :&DR_TABLE[SR<<1]   */
                    234:     int  SL;                /* sustin level    :SL_TALBE[SL]       */
                    235:     int *RR;                /* release rate    :&DR_TABLE[RR<<2+2] */
                    236:     unsigned char SEG;      /* SSG EG type     :SSGEG              */
                    237:     unsigned char ksr;      /* key scale rate  :kcode>>(3-KSR)     */
                    238:     unsigned int mul;       /* multiple        :ML_TABLE[ML]       */
                    239:     unsigned int Cnt;       /* frequency count :                   */
                    240:     int Incr;               /* frequency step  :                   */
                    241:     /* envelope generator state */
                    242:     unsigned char evm;      /* envelope phase                      */
                    243:     signed int evc;         /* envelope counter                    */
                    244:     signed int eve;         /* envelope counter end point          */
                    245:     signed int evs;         /* envelope counter step               */
                    246:     signed int evsa;        /* envelope step for AR                */
                    247:     signed int evsd;        /* envelope step for DR                */
                    248:     signed int evss;        /* envelope step for SR                */
                    249:     signed int evsr;        /* envelope step for RR                */
                    250:     /* LFO */
                    251:     unsigned char ams;
                    252:     unsigned char pms;
                    253: }FM_SLOT;
                    254: 
                    255: 
                    256: typedef struct fm_chan {
                    257:     FM_SLOT SLOT[4];
                    258:     unsigned char PAN;          /* PAN NONE,LEFT,RIGHT or CENTER       */
                    259:     unsigned char ALGO;         /* algorythm                           */
                    260:     unsigned char FB;           /* feed back       :&FB_TABLE[FB<<8]   */
                    261:     int op1_out;                /* op1 output foe beedback             */
                    262:     /* algorythm state */
                    263:     int *connect1;              /* operator 1 connection pointer       */
                    264:     int *connect2;              /* operator 2 connection pointer       */
                    265:     int *connect3;              /* operator 3 connection pointer       */
                    266:     int *connect4;              /* operator 4 connection pointer       */
                    267:     /* phase generator state */
                    268:     unsigned int  fc;           /* fnum,blk        :calcrated          */
                    269:     unsigned char fn_h;         /* freq latch      :                   */
                    270:     unsigned char kcode;        /* key code        :                   */
                    271: } FM_CH;
                    272: 
                    273: /* OPN/OPM common state */
                    274: typedef struct fm_state {
                    275:     unsigned char index;        /* chip index (number of chip) */
                    276:     int clock;                  /* master clock  (Hz)  */
                    277:     int rate;                   /* sampling rate (Hz)  */
                    278:     int freqbase;               /* frequency base      */
                    279:     double TimerBase;           /* Timer base time     */
                    280:     unsigned char address;      /* address register    */
                    281:     unsigned char irq;          /* interrupt level     */
                    282:     unsigned char irqmask;      /* irq mask            */
                    283:     unsigned char status;       /* status flag         */
                    284:     unsigned int mode;          /* mode  CSM / 3SLOT   */
                    285:     int TA;                     /* timer a             */
                    286:     int TAC;                    /* timer a counter     */
                    287:     unsigned char TB;           /* timer b             */
                    288:     int TBC;                    /* timer b counter     */
                    289:     /* speedup customize */
                    290:     /* time tables */
                    291:     signed int DT_TABLE[8][32];     /* detune tables       */
                    292:     signed int AR_TABLE[94];    /* atttack rate tables */
                    293:     signed int DR_TABLE[94];    /* decay rate tables   */
                    294:     /* LFO */
                    295:     unsigned int LFOCnt;
                    296:     unsigned int LFOIncr;
                    297:     /* Extention Timer and IRQ handler */
                    298:     FM_TIMERHANDLER Timer_Handler;
                    299:     FM_IRQHANDLER   IRQ_Handler;
                    300:     /* timer model single / interval */
                    301:     unsigned char timermodel;
                    302: }FM_ST;
                    303: 
                    304: /* OPN 3slot struct */
                    305: typedef struct opn_3slot {
                    306:     unsigned int  fc[3];        /* fnum3,blk3  :calcrated */
                    307:     unsigned char fn_h[3];      /* freq3 latch            */
                    308:     unsigned char kcode[3];     /* key code    :          */
                    309: }FM_3SLOT;
                    310: 
                    311: /* adpcm type A and type B struct */
                    312: typedef struct adpcm_state {
                    313:   unsigned char flag;       /* port state */
                    314:   unsigned char flagMask;   /* arrived    */
                    315:   unsigned char now_data;
                    316:   unsigned int now_addr;
                    317:   unsigned int now_step;
                    318:   unsigned int step;
                    319:   unsigned int start;
                    320:   unsigned int end;
                    321:   unsigned int delta;
                    322:   int IL;
                    323:   int volume;
                    324:   int *pan;     /* &outd[OPN_xxxx] */
                    325:   int /*adpcmm,*/ adpcmx, adpcmd;
                    326:   int adpcml;           /* hiro-shi!! */
                    327: 
                    328:   /* leveling and re-sampling state for DELTA-T */
                    329:   int volume_w_step;   /* volume with step rate */
                    330:   int next_leveling;   /* leveling value        */
                    331:   int sample_step;     /* step of re-sampling   */
                    332: }ADPCM_CH;
                    333: 
                    334: /* OPN/A/B common state */
                    335: typedef struct opn_f {
                    336:     unsigned char type;     /* chip type         */
                    337:     FM_ST ST;               /* general state     */
                    338:     FM_3SLOT SL3;           /* 3 slot mode state */
                    339:     FM_CH *P_CH;            /* pointer of CH     */
                    340:     unsigned int FN_TABLE[2048]; /* fnumber -> increment counter */
                    341: } FM_OPN;
                    342: 
                    343: /* here's the virtual YM2203(OPN) (Used by YM2608 / YM2612)  */
                    344: typedef struct ym2203_f {
                    345:     FM_OPN OPN;             /* OPN state         */
                    346: /*  FMSAMPLE *Buf;*/            /* sound buffer      */
                    347:     FM_CH CH[3];            /* channel state     */
                    348: } YM2203;
                    349: 
                    350: /* here's the virtual YM2610 */
                    351: typedef struct ym2610_f {
                    352:     FM_OPN OPN;                     /* OPN state    */
                    353: /*  FMSAMPLE *Buf[YM2610_NUMBUF];*/ /* sound buffer */
                    354:     FM_CH CH[6];                    /* channel state */
                    355:     int address1;   /* address register1 */
                    356:     /**** ADPCM control ****/
                    357:     char *pcmbuf[2];
                    358:     unsigned int pcm_size[2];
                    359:     int *TL_adpcmb;
                    360:     ADPCM_CH adpcm[7];          /* normal ADPCM & deltaT ADPCM */
                    361:     unsigned int adpcmreg[2][0x30];
                    362:     int port0state, port0control, port0shift;
                    363:     int port1state, port1control, port1shift;
                    364:     unsigned char adpcm_arrivedEndAddress,adpcm_statusmask;
                    365: } YM2610;
                    366: 
                    367: /* here's the virtual YM2608 */
                    368: typedef YM2610 YM2608;
                    369: 
                    370: /* here's the virtual YM2612 */
                    371: typedef struct ym2612_f {
                    372:     FM_OPN OPN;                     /* OPN state       */
                    373: /*  FMSAMPLE *Buf[YM2612_NUMBUF];*/ /* sound buffer */
                    374:     FM_CH CH[6];                    /* channel state */
                    375:     int address1;   /* address register1 */
                    376:     /* dac output (YM2612) */
                    377:     int dacen;
                    378:     int dacout;
                    379: } YM2612;
                    380: 
                    381: /* here's the virtual YM2151(OPM)  */
                    382: typedef struct ym2151_f {
                    383: /*  FMSAMPLE *Buf[YM2151_NUMBUF];*//* sound buffers    */
                    384:     FM_ST ST;                   /* general state     */
                    385:     FM_CH CH[8];                /* channel state     */
                    386:     unsigned char NReg;         /* noise enable,freq */
                    387:     unsigned char pmd;          /* LFO pmd level     */
                    388:     unsigned char amd;          /* LFO amd level     */
                    389:     unsigned char ctw;          /* CT0,1 and waveform */
                    390:     unsigned int KC_TABLE[8*12*64+950];/* keycode,keyfunction -> count */
                    391:     void (*PortWrite)(int offset,int data);/*  callback when write CT0/CT1 */
                    392: } YM2151;
                    393: 
                    394: /* -------------------- tables --------------------- */
                    395: 
                    396: /* key scale level */
                    397: /* !!!!! preliminary !!!!! */
                    398: 
                    399: #define DV (1/EG_STEP)
                    400: static const unsigned char KSL[32]=
                    401: {
                    402: #if 1
                    403:  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                    404: #else
                    405:  0.000/DV , 0.000/DV , 0.000/DV , 0.000/DV ,    /* OCT 0 */
                    406:  0.000/DV , 0.000/DV , 0.000/DV , 1.875/DV ,    /* OCT 1 */
                    407:  0.000/DV , 0.000/DV , 3.000/DV , 4.875/DV ,    /* OCT 2 */
                    408:  0.000/DV , 3.000/DV , 6.000/DV , 7.875/DV ,    /* OCT 3 */
                    409:  0.000/DV , 6.000/DV , 9.000/DV ,10.875/DV ,    /* OCT 4 */
                    410:  0.000/DV , 9.000/DV ,12.000/DV ,13.875/DV ,    /* OCT 5 */
                    411:  0.000/DV ,12.000/DV ,15.000/DV ,16.875/DV ,    /* OCT 6 */
                    412:  0.000/DV ,15.000/DV ,18.000/DV ,19.875/DV      /* OCT 7 */
                    413: #endif
                    414: };
                    415: #undef DV
                    416: 
                    417: /* OPN key frequency number -> key code follow table */
                    418: /* fnum higher 4bit -> keycode lower 2bit */
                    419: static const char OPN_FKTABLE[16]={0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
                    420: 
                    421: static const int KC_TO_SEMITONE[16]={
                    422:     /*translate note code KC into more usable number of semitone*/
                    423:     0*64, 1*64, 2*64, 3*64,
                    424:     3*64, 4*64, 5*64, 6*64,
                    425:     6*64, 7*64, 8*64, 9*64,
                    426:     9*64,10*64,11*64,12*64
                    427: };
                    428: 
                    429: static const int DT2_TABLE[4]={ /* 4 DT2 values */
                    430: /*
                    431:  *   DT2 defines offset in cents from base note
                    432:  *
                    433:  *   The table below defines offset in deltas table...
                    434:  *   User's Manual page 22
                    435:  *   Values below were calculated using formula:  value = orig.val * 1.5625
                    436:  *
                    437:  * DT2=0 DT2=1 DT2=2 DT2=3
                    438:  * 0     600   781   950
                    439:  */
                    440:     0,    384,  500,  608
                    441: };
                    442: 
                    443: /* sustain lebel table (3db per step) */
                    444: /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
                    445: #define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
                    446: static const int SL_TABLE[16]={
                    447:  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
                    448:  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
                    449: };
                    450: #undef SC
                    451: 
                    452: #ifdef TL_SAVE_MEM
                    453:   #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
                    454: #else
                    455:   #define TL_MAX (EG_ENT*4) /* tl + ksr + envelope + sinwave */
                    456: #endif
                    457: 
                    458: /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
                    459: /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
                    460: /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
                    461: static int *TL_TABLE;
                    462: 
                    463: /* pointers to TL_TABLE with sinwave output offset */
                    464: static signed int *SIN_TABLE[SIN_ENT];
                    465: 
                    466: /* envelope output curve table */
                    467: #ifdef SEG_SUPPORT
                    468: /* attack + decay + SSG upside + OFF */
                    469: static int ENV_CURVE[3*EG_ENT+1];
                    470: #else
                    471: /* attack + decay + OFF */
                    472: static int ENV_CURVE[2*EG_ENT+1];
                    473: #endif
                    474: /* envelope counter conversion table when change Decay to Attack phase */
                    475: static int DRAR_TABLE[EG_ENT];
                    476: 
                    477: #define OPM_DTTABLE OPN_DTTABLE
                    478: static char OPN_DTTABLE[4 * 32]={
                    479: /* this table is YM2151 and YM2612 data */
                    480: /* FD=0 */
                    481:   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    482:   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    483: /* FD=1 */
                    484:   0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
                    485:   2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
                    486: /* FD=2 */
                    487:   1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
                    488:   5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
                    489: /* FD=3 */
                    490:   2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
                    491:   8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
                    492: };
                    493: 
                    494: /* multiple table */
                    495: #define ML 2
                    496: static const int MUL_TABLE[4*16]= {
                    497: /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
                    498:    0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
                    499:    8.00*ML, 9.00*ML,10.00*ML,11.00*ML,12.00*ML,13.00*ML,14.00*ML,15.00*ML,
                    500: /* DT2=1 *SQL(2)   */
                    501:    0.71*ML, 1.41*ML, 2.82*ML, 4.24*ML, 5.65*ML, 7.07*ML, 8.46*ML, 9.89*ML,
                    502:   11.30*ML,12.72*ML,14.10*ML,15.55*ML,16.96*ML,18.37*ML,19.78*ML,21.20*ML,
                    503: /* DT2=2 *SQL(2.5) */
                    504:    0.78*ML, 1.57*ML, 3.14*ML, 4.71*ML, 6.28*ML, 7.85*ML, 9.42*ML,10.99*ML,
                    505:   12.56*ML,14.13*ML,15.70*ML,17.27*ML,18.84*ML,20.41*ML,21.98*ML,23.55*ML,
                    506: /* DT2=3 *SQL(3)   */
                    507:    0.87*ML, 1.73*ML, 3.46*ML, 5.19*ML, 6.92*ML, 8.65*ML,10.38*ML,12.11*ML,
                    508:   13.84*ML,15.57*ML,17.30*ML,19.03*ML,20.76*ML,22.49*ML,24.22*ML,25.95*ML
                    509: };
                    510: #undef ML
                    511: 
                    512: #ifdef LFO_SUPPORT
                    513: /* LFO frequency timer table */
                    514: static int OPM_LFO_TABLE[256];
                    515: #endif
                    516: 
                    517: /* dummy attack / decay rate ( when rate == 0 ) */
                    518: static int RATE_0[32]=
                    519: {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
                    520: 
                    521: /* -------------------- state --------------------- */
                    522: 
                    523: /* some globals */
                    524: #define TYPE_SSG    0x01    /* SSG support       */
                    525: #define TYPE_OPN    0x02    /* OPN device        */
                    526: #define TYPE_LFOPAN 0x04    /* OPN type LFO and PAN */
                    527: #define TYPE_6CH    0x08    /* FM 6CH / 3CH      */
                    528: #define TYPE_DAC    0x10    /* YM2612's DAC device */
                    529: #define TYPE_ADPCM  0x20    /* ADPCM device      */
                    530: 
                    531: #define TYPE_YM2203 (TYPE_SSG)
                    532: #define TYPE_YM2608 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
                    533: #define TYPE_YM2610 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
                    534: #define TYPE_YM2612 (TYPE_6CH |TYPE_LFOPAN |TYPE_DAC)
                    535: 
                    536: static int FMNumChips;      /* total # of FM emulated */
                    537: 
                    538: /* work table */
                    539: static void *cur_chip = 0;  /* current chip point */
                    540: 
                    541: /* currenct chip state */
                    542: static FM_ST     *State;
                    543: static FMSAMPLE  *bufL,*bufR;
                    544: static FM_CH     *cch[8];
                    545: static signed int outd[4];
                    546: 
                    547: /* operator connection work */
                    548: static int feedback2;       /* connect for operator 2 */
                    549: static int feedback3;       /* connect for operator 3 */
                    550: static int feedback4;       /* connect for operator 4 */
                    551: 
                    552: /* log output level */
                    553: #define LOG_ERR  3      /* ERROR       */
                    554: #define LOG_WAR  2      /* WARNING     */
                    555: #define LOG_INF  1      /* INFORMATION */
                    556: 
                    557: #define LOG_LEVEL LOG_INF
                    558: 
                    559: #ifndef __RAINE__
                    560: static void Log(int level,char *format,...)
                    561: {
                    562:     int i;
                    563:     va_list argptr;
                    564: 
                    565:     if( level < LOG_LEVEL ) return;
                    566:     va_start(argptr,format);
                    567:     /* */
                    568:     if (errorlog) vfprintf( errorlog, format , argptr);
                    569: }
                    570: #endif
                    571: 
                    572: /* --------------- Customize External interface port (SSG,Timer,etc) ---------------*/
                    573: #include "fmext.c"
                    574: 
                    575: /* --------------------- subroutines  --------------------- */
                    576: 
                    577: INLINE int Limit( int val, int max, int min ) {
                    578:     if ( val > max )
                    579:         val = max;
                    580:     else if ( val < min )
                    581:         val = min;
                    582: 
                    583:     return val;
                    584: }
                    585: 
                    586: /* status set and IRQ handling */
                    587: INLINE void FM_STATUS_SET(FM_ST *ST,int flag)
                    588: {
                    589:     /* set status flag */
                    590:     ST->status |= flag;
                    591:     if ( !(ST->irq) && (ST->status & ST->irqmask) )
                    592:     {
                    593:         ST->irq = 1;
                    594:         /* callback user interrupt handler (IRQ is OFF to ON) */
                    595:         if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->index,1);
                    596:     }
                    597: }
                    598: 
                    599: /* status reset and IRQ handling */
                    600: INLINE void FM_STATUS_RESET(FM_ST *ST,int flag)
                    601: {
                    602:     /* reset status flag */
                    603:     ST->status &=~flag;
                    604:     if ( (ST->irq) && !(ST->status & ST->irqmask) )
                    605:     {
                    606:         ST->irq = 0;
                    607:         /* callback user interrupt handler (IRQ is ON to OFF) */
                    608:         if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->index,0);
                    609:     }
                    610: }
                    611: 
                    612: /* IRQ mask set */
                    613: INLINE void FM_IRQMASK_SET(FM_ST *ST,int flag)
                    614: {
                    615:     ST->irqmask = flag;
                    616:     /* IRQ handling check */
                    617:     FM_STATUS_SET(ST,0);
                    618:     FM_STATUS_RESET(ST,0);
                    619: }
                    620: 
                    621: /* ----- key on  ----- */
                    622: INLINE void FM_KEYON(FM_CH *CH , int s )
                    623: {
                    624:     FM_SLOT *SLOT = &CH->SLOT[s];
                    625:     if( SLOT->evm<= ENV_MOD_RR)
                    626:     {
                    627:         /* set envelope counter from envleope output */
                    628: 
                    629:         /* sin wave restart */
                    630:         SLOT->Cnt = 0;
                    631:         if( s == SLOT1 ) CH->op1_out = 0;
                    632:         /* set attack */
                    633: #ifdef SEG_SUPPORT
                    634:         if( SLOT->SEG&8 ) SLOT->evm = ENV_SSG_AR; /* jp 09/06/99 */
                    635:         else
                    636: #endif
                    637:         SLOT->evm = ENV_MOD_AR;
                    638:         SLOT->evs = SLOT->evsa;
                    639: #if 0
                    640:         /* convert decay count to attack count */
                    641:         /* --- This caused the problem by credit sound of paper boy. --- */
                    642:         SLOT->evc = EG_AST + DRAR_TABLE[ENV_CURVE[SLOT->evc>>ENV_BITS]];/* + SLOT->evs;*/
                    643: #else
                    644:         /* reset attack counter */
                    645:         SLOT->evc = EG_AST;
                    646: #endif
                    647:         SLOT->eve = EG_AED;
                    648:     }
                    649: }
                    650: /* ----- key off ----- */
                    651: INLINE void FM_KEYOFF(FM_CH *CH , int s )
                    652: {
                    653:     FM_SLOT *SLOT = &CH->SLOT[s];
                    654:     if( SLOT->evm > ENV_MOD_RR)
                    655:     {
                    656:         /* set envelope counter from envleope output */
                    657:         SLOT->evm = ENV_MOD_RR;
                    658:         if( !(SLOT->evc&EG_DST) )
                    659:             SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
                    660:         SLOT->eve = EG_DED;
                    661:         SLOT->evs = SLOT->evsr;
                    662:     }
                    663: }
                    664: 
                    665: /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
                    666: /* return : envelope output */
                    667: INLINE signed int FM_CALC_SLOT( FM_SLOT *SLOT )
                    668: {
                    669:     /* calcrate phage generator */
                    670:     SLOT->Cnt += SLOT->Incr;
                    671:     /* calcrate envelope generator */
                    672:     if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
                    673:     {
                    674:         switch( SLOT->evm ){
                    675:         case ENV_MOD_AR: /* ATTACK -> DECAY1 */
                    676:             /* next DR */
                    677:             SLOT->evm = ENV_MOD_DR;
                    678:             SLOT->evc = EG_DST;
                    679:             SLOT->eve = SLOT->SL;
                    680:             SLOT->evs = SLOT->evsd;
                    681:             break;
                    682:         case ENV_MOD_DR: /* DECAY -> SUSTAIN */
                    683:             SLOT->evm = ENV_MOD_SR;
                    684:             SLOT->evc = SLOT->SL;
                    685:             SLOT->eve = EG_DED;
                    686:             SLOT->evs = SLOT->evss;
                    687:             break;
                    688:         case ENV_MOD_RR: /* RR -> OFF & STOP */
                    689:             SLOT->evm = ENV_MOD_OFF;
                    690:         case ENV_MOD_SR: /* SR -> OFF & STOP */
                    691:             SLOT->evc = EG_OFF;
                    692:             SLOT->eve = EG_OFF+1;
                    693:             SLOT->evs = 0;
                    694:             break;
                    695: #ifdef SEG_SUPPORT
                    696:         case ENV_SSG_AR: /* SSG ATTACK */
                    697:             if( SLOT->SEG&4){   /* start direction */
                    698:                 /* next SSG-SR (upside start ) */
                    699:                 SLOT->evm = ENV_SSG_SR;
                    700:                 SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
                    701:                 SLOT->eve = EG_UED;
                    702:                 SLOT->evs = SLOT->evss;
                    703:             }else{
                    704:                 /* next SSG-DR (downside start ) */
                    705:                 SLOT->evm = ENV_SSG_DR;
                    706:                 SLOT->evc = EG_DST;
                    707:                 SLOT->eve = EG_DED;
                    708:                 SLOT->evs = SLOT->evsd;
                    709:             }
                    710:             break;
                    711:         case ENV_SSG_DR:    /* SEG down side */
                    712:             if( SLOT->SEG&2){
                    713:                 /* reverce */
                    714:                 SLOT->evm = ENV_SSG_SR;
                    715:                 SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
                    716:                 SLOT->eve = EG_UED;
                    717:                 SLOT->evs = SLOT->evss;
                    718:             }else{
                    719:                 /* again */
                    720:                 SLOT->evc = EG_DST;
                    721:             }
                    722:             /* hold */
                    723:             if( SLOT->SEG&1) SLOT->evs = 0;
                    724:             break;
                    725:         case ENV_SSG_SR:    /* upside */
                    726:             if( SLOT->SEG&2){
                    727:                 /* reverce  */
                    728:                 SLOT->evm = ENV_SSG_DR;
                    729:                 SLOT->evc = EG_DST;
                    730:                 SLOT->eve = EG_DED;
                    731:                 SLOT->evs = SLOT->evsd;
                    732:             }else{
                    733:                 /* again */
                    734:                 SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
                    735:             }
                    736:             /* hold check */
                    737:             if( SLOT->SEG&1) SLOT->evs = 0;
                    738:             break;
                    739: #endif
                    740:         }
                    741:     }
                    742:     /* calcrate envelope */
                    743: #if 0 /* ifdef TL_SAVE_MEM */
                    744:     signed int env_out = SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]; /* LFO_out[SLOT->AMS] */
                    745:     if(env_out >= (EG_ENT-1) ) return EG_ENT-1;
                    746:     return env_out;
                    747: #else
                    748:     return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]; /* LFO_out[SLOT->AMS] */
                    749: #endif
                    750: }
                    751: 
                    752: /* set algorythm connection */
                    753: static void set_algorythm( FM_CH *CH )
                    754: {
                    755:     signed int *carrier = &outd[CH->PAN];
                    756: 
                    757:     /* setup connect algorythm */
                    758:     switch( CH->ALGO ){
                    759:     case 0:
                    760:         /*  PG---S1---S2---S3---S4---OUT */
                    761:         CH->connect1 = &feedback2;
                    762:         CH->connect2 = &feedback3;
                    763:         CH->connect3 = &feedback4;
                    764:         break;
                    765:     case 1:
                    766:         /*  PG---S1-+-S3---S4---OUT */
                    767:         /*  PG---S2-+               */
                    768:         CH->connect1 = &feedback3;
                    769:         CH->connect2 = &feedback3;
                    770:         CH->connect3 = &feedback4;
                    771:         break;
                    772:     case 2:
                    773:         /* PG---S1------+-S4---OUT */
                    774:         /* PG---S2---S3-+          */
                    775:         CH->connect1 = &feedback4;
                    776:         CH->connect2 = &feedback3;
                    777:         CH->connect3 = &feedback4;
                    778:         break;
                    779:     case 3:
                    780:         /* PG---S1---S2-+-S4---OUT */
                    781:         /* PG---S3------+          */
                    782:         CH->connect1 = &feedback2;
                    783:         CH->connect2 = &feedback4;
                    784:         CH->connect3 = &feedback4;
                    785:         break;
                    786:     case 4:
                    787:         /* PG---S1---S2-+--OUT */
                    788:         /* PG---S3---S4-+      */
                    789:         CH->connect1 = &feedback2;
                    790:         CH->connect2 = carrier;
                    791:         CH->connect3 = &feedback4;
                    792:         break;
                    793:     case 5:
                    794:         /*         +-S2-+     */
                    795:         /* PG---S1-+-S3-+-OUT */
                    796:         /*         +-S4-+     */
                    797:         CH->connect1 = 0;   /* special mark */
                    798:         CH->connect2 = carrier;
                    799:         CH->connect3 = carrier;
                    800:         break;
                    801:     case 6:
                    802:         /* PG---S1---S2-+     */
                    803:         /* PG--------S3-+-OUT */
                    804:         /* PG--------S4-+     */
                    805:         CH->connect1 = &feedback2;
                    806:         CH->connect2 = carrier;
                    807:         CH->connect3 = carrier;
                    808:         break;
                    809:     case 7:
                    810:         /* PG---S1-+     */
                    811:         /* PG---S2-+-OUT */
                    812:         /* PG---S3-+     */
                    813:         /* PG---S4-+     */
                    814:         CH->connect1 = carrier;
                    815:         CH->connect2 = carrier;
                    816:         CH->connect3 = carrier;
                    817:     }
                    818:     CH->connect4 = carrier;
                    819: }
                    820: 
                    821: /* set detune & multiple */
                    822: INLINE void set_det_mul(FM_ST *ST,FM_CH *CH,FM_SLOT *SLOT,int v)
                    823: {
                    824:     SLOT->mul = MUL_TABLE[v&0x0f];
                    825:     SLOT->DT  = ST->DT_TABLE[(v>>4)&7];
                    826:     CH->SLOT[SLOT1].Incr=-1;
                    827: }
                    828: 
                    829: /* set total level */
                    830: INLINE void set_tl(FM_CH *CH,FM_SLOT *SLOT , int v,int csmflag)
                    831: {
                    832:     v &= 0x7f;
                    833:     v = (v<<7)|v; /* 7bit -> 14bit */
                    834:     SLOT->TL = (v*EG_ENT)>>14;
                    835:     if( !csmflag )
                    836:     {   /* not CSM latch total level */
                    837:         SLOT->TLL = SLOT->TL + KSL[CH->kcode];
                    838:     }
                    839: }
                    840: 
                    841: /* set attack rate & key scale  */
                    842: INLINE void set_ar_ksr(FM_CH *CH,FM_SLOT *SLOT,int v,signed int *ar_table)
                    843: {
                    844:     SLOT->KSR  = 3-(v>>6);
                    845:     SLOT->AR   = (v&=0x1f) ? &ar_table[v<<1] : RATE_0;
                    846:     SLOT->evsa = SLOT->AR[SLOT->ksr];
                    847:     if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
                    848:     CH->SLOT[SLOT1].Incr=-1;
                    849: }
                    850: /* set decay rate */
                    851: INLINE void set_dr(FM_SLOT *SLOT,int v,signed int *dr_table)
                    852: {
                    853:     SLOT->DR = (v&=0x1f) ? &dr_table[v<<1] : RATE_0;
                    854:     SLOT->evsd = SLOT->DR[SLOT->ksr];
                    855:     if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
                    856: }
                    857: /* set sustain rate */
                    858: INLINE void set_sr(FM_SLOT *SLOT,int v,signed int *dr_table)
                    859: {
                    860:     SLOT->SR = (v&=0x1f) ? &dr_table[v<<1] : RATE_0;
                    861:     SLOT->evss = SLOT->SR[SLOT->ksr];
                    862:     if( SLOT->evm == ENV_MOD_SR ) SLOT->evs = SLOT->evss;
                    863: }
                    864: /* set release rate */
                    865: INLINE void set_sl_rr(FM_SLOT *SLOT,int v,signed int *dr_table)
                    866: {
                    867:     SLOT->SL = SL_TABLE[(v>>4)];
                    868:     SLOT->RR = &dr_table[((v&0x0f)<<2)|2];
                    869:     SLOT->evsr = SLOT->RR[SLOT->ksr];
                    870:     if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
                    871: }
                    872: 
                    873: /* operator output calcrator */
                    874: #define OP_OUT(slot,env,con)   SIN_TABLE[((slot.Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
                    875: /* ---------- calcrate one of channel ---------- */
                    876: INLINE void FM_CALC_CH( FM_CH *CH )
                    877: {
                    878:     int op_out;
                    879:     int env_out;
                    880: 
                    881:     feedback2 = feedback3 = feedback4 = 0;
                    882: 
                    883:     /* SLOT 1 */
                    884:     env_out=FM_CALC_SLOT(&CH->SLOT[SLOT1]);
                    885:     if( env_out < EG_ENT-1 )
                    886:     {
                    887:         if( CH->FB){
                    888:             /* with self feed back */
                    889:             op_out = CH->op1_out;
                    890:             CH->op1_out = OP_OUT(CH->SLOT[SLOT1],env_out,(CH->op1_out>>CH->FB) /* +LFOOut[SLOT->AMS]*/ );
                    891:             op_out = (op_out + CH->op1_out)/2;
                    892:         }else{
                    893:             /* without self feed back */
                    894:             op_out = OP_OUT(CH->SLOT[SLOT1],env_out,0 /* +LFOOut[SLOT->AMS]*/ );
                    895:         }
                    896:         /* output slot1 */
                    897:         if( !CH->connect1 )
                    898:         {
                    899:             /* algorythm 5  */
                    900:             feedback2 = feedback3 = feedback4 = op_out;
                    901:         }else{
                    902:             /* other algorythm */
                    903:             *CH->connect1 += op_out;
                    904:         }
                    905:     }
                    906:     /* SLOT 2 */
                    907:     env_out=FM_CALC_SLOT(&CH->SLOT[SLOT2]);
                    908:     if( env_out < EG_ENT-1 )
                    909:         *CH->connect2 += OP_OUT(CH->SLOT[SLOT2],env_out, feedback2 /* +LFOOut[SLOT->AMS]*/  );
                    910:     /* SLOT 3 */
                    911:     env_out=FM_CALC_SLOT(&CH->SLOT[SLOT3]);
                    912:     if( env_out < EG_ENT-1 )
                    913:         *CH->connect3 += OP_OUT(CH->SLOT[SLOT3],env_out, feedback3  /* +LFOOut[SLOT->AMS]*/ );
                    914:     /* SLOT 4 */
                    915:     env_out=FM_CALC_SLOT(&CH->SLOT[SLOT4]);
                    916:     if( env_out < EG_ENT-1 )
                    917:         *CH->connect4 += OP_OUT(CH->SLOT[SLOT4],env_out, feedback4  /* +LFOOut[SLOT->AMS]*/ );
                    918: }
                    919: /* ---------- frequency counter for operater update ---------- */
                    920: INLINE void CALC_FCSLOT(FM_SLOT *SLOT , int fc , int kc )
                    921: {
                    922:     int ksr;
                    923: 
                    924:     /* frequency step counter */
                    925:     SLOT->Incr= (fc+SLOT->DT[kc])*SLOT->mul;
                    926:     ksr = kc >> SLOT->KSR;
                    927:     if( SLOT->ksr != ksr )
                    928:     {
                    929:         SLOT->ksr = ksr;
                    930:         /* attack , decay rate recalcration */
                    931:         SLOT->evsa = SLOT->AR[ksr];
                    932:         SLOT->evsd = SLOT->DR[ksr];
                    933:         SLOT->evss = SLOT->SR[ksr];
                    934:         SLOT->evsr = SLOT->RR[ksr];
                    935:     }
                    936:     SLOT->TLL = SLOT->TL + KSL[kc];
                    937: }
                    938: 
                    939: /* ---------- frequency counter  ---------- */
                    940: INLINE void CALC_FCOUNT(FM_CH *CH )
                    941: {
                    942:     if( CH->SLOT[SLOT1].Incr==-1){
                    943:         int fc = CH->fc;
                    944:         int kc = CH->kcode;
                    945:         CALC_FCSLOT(&CH->SLOT[SLOT1] , fc , kc );
                    946:         CALC_FCSLOT(&CH->SLOT[SLOT2] , fc , kc );
                    947:         CALC_FCSLOT(&CH->SLOT[SLOT3] , fc , kc );
                    948:         CALC_FCSLOT(&CH->SLOT[SLOT4] , fc , kc );
                    949:     }
                    950: }
                    951: 
                    952: /* ---------- frequency counter  ---------- */
                    953: INLINE void OPM_CALC_FCOUNT(YM2151 *OPM , FM_CH *CH )
                    954: {
                    955:     if( CH->SLOT[SLOT1].Incr==-1)
                    956:     {
                    957:         int fc = CH->fc;
                    958:         int kc = CH->kcode;
                    959:         CALC_FCSLOT(&CH->SLOT[SLOT1] , OPM->KC_TABLE[fc + CH->SLOT[SLOT1].DT2] , kc );
                    960:         CALC_FCSLOT(&CH->SLOT[SLOT2] , OPM->KC_TABLE[fc + CH->SLOT[SLOT2].DT2] , kc );
                    961:         CALC_FCSLOT(&CH->SLOT[SLOT3] , OPM->KC_TABLE[fc + CH->SLOT[SLOT3].DT2] , kc );
                    962:         CALC_FCSLOT(&CH->SLOT[SLOT4] , OPM->KC_TABLE[fc + CH->SLOT[SLOT4].DT2] , kc );
                    963:     }
                    964: }
                    965: /* ----------- initialize time tabls ----------- */
                    966: static void init_timetables( FM_ST *ST , char *DTTABLE , int ARRATE , int DRRATE )
                    967: {
                    968:     int i,d;
                    969:     double rate;
                    970: 
                    971:     /* make detune table */
                    972:     for (d = 0;d <= 3;d++){
                    973:         for (i = 0;i <= 31;i++){
                    974:             rate = (double)DTTABLE[d*32 + i] * ST->freqbase / 4096 * FREQ_RATE;
                    975:             ST->DT_TABLE[d][i]   =  rate;
                    976:             ST->DT_TABLE[d+4][i] = -rate;
                    977:         }
                    978:     }
                    979:     /* make attack rate & decay rate tables */
                    980:     for (i = 0;i < 4;i++) ST->AR_TABLE[i] = ST->DR_TABLE[i] = 0;
                    981:     for (i = 4;i < 64;i++){
                    982:         rate  = (double)ST->freqbase / 4096.0;      /* frequency rate */
                    983:         if( i < 60 ) rate *= 1.0+(i&3)*0.25;        /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
                    984:         rate *= 1<<((i>>2)-1);                      /* b2-5 : shift bit */
                    985:         rate *= (double)(EG_ENT<<ENV_BITS);
                    986:         ST->AR_TABLE[i] = rate / ARRATE;
                    987:         ST->DR_TABLE[i] = rate / DRRATE;
                    988:     }
                    989:     ST->AR_TABLE[62] = EG_AED-1;
                    990:     ST->AR_TABLE[63] = EG_AED-1;
                    991:     for (i = 64;i < 94 ;i++){   /* make for overflow area */
                    992:         ST->AR_TABLE[i] = ST->AR_TABLE[63];
                    993:         ST->DR_TABLE[i] = ST->DR_TABLE[63];
                    994:     }
                    995: 
                    996: #if 0
                    997:     for (i = 0;i < 64 ;i++){    /* make for overflow area */
                    998:         Log(LOG_WAR,"rate %2d , ar %f ms , dr %f ms \n",i,
                    999:             ((double)(EG_ENT<<ENV_BITS) / ST->AR_TABLE[i]) * (1000.0 / ST->rate),
                   1000:             ((double)(EG_ENT<<ENV_BITS) / ST->DR_TABLE[i]) * (1000.0 / ST->rate) );
                   1001:     }
                   1002: #endif
                   1003: }
                   1004: 
                   1005: /* ---------- reset one of channel  ---------- */
                   1006: static void reset_channel( FM_ST *ST , FM_CH *CH , int chan )
                   1007: {
                   1008:     int c,s;
                   1009: 
                   1010:     ST->mode   = 0; /* normal mode */
                   1011:     FM_STATUS_RESET(ST,0xff);
                   1012:     ST->TA     = 0;
                   1013:     ST->TAC    = 0;
                   1014:     ST->TB     = 0;
                   1015:     ST->TBC    = 0;
                   1016: 
                   1017:     for( c = 0 ; c < chan ; c++ )
                   1018:     {
                   1019:         CH[c].fc = 0;
                   1020:         CH[c].PAN = OPN_CENTER; /* or OPM_CENTER */
                   1021:         for(s = 0 ; s < 4 ; s++ )
                   1022:         {
                   1023:             CH[c].SLOT[s].SEG = 0;
                   1024:             CH[c].SLOT[s].evm = ENV_MOD_OFF;
                   1025:             CH[c].SLOT[s].evc = EG_OFF;
                   1026:             CH[c].SLOT[s].eve = EG_OFF+1;
                   1027:             CH[c].SLOT[s].evs = 0;
                   1028:         }
                   1029:     }
                   1030: }
                   1031: 
                   1032: /* ---------- generic table initialize ---------- */
                   1033: static int FMInitTable( void )
                   1034: {
                   1035:     int s,t;
                   1036:     double rate;
                   1037:     int i,j;
                   1038:     double pom;
                   1039: 
                   1040:     /* allocate total level table */
                   1041:     TL_TABLE = malloc(TL_MAX*2*sizeof(int));
                   1042:     if( TL_TABLE == 0 ) return 0;
                   1043:     /* make total level table */
                   1044:     for (t = 0;t < EG_ENT-1 ;t++){
                   1045:         rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20);   /* dB -> voltage */
                   1046:         TL_TABLE[       t] =  (int)rate;
                   1047:         TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
                   1048: /*      Log(LOG_INF,"TotalLevel(%3d) = %x\n",t,TL_TABLE[t]);*/
                   1049:     }
                   1050:     /* fill volume off area */
                   1051:     for ( t = EG_ENT-1; t < TL_MAX ;t++){
                   1052:         TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
                   1053:     }
                   1054: 
                   1055:     /* make sinwave table (total level offet) */
                   1056:      /* degree 0 = degree 180                   = off */
                   1057:     SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2]         = &TL_TABLE[EG_ENT-1];
                   1058:     for (s = 1;s <= SIN_ENT/4;s++){
                   1059:         pom = sin(2*PI*s/SIN_ENT); /* sin     */
                   1060:         pom = 20*log10(1/pom);     /* decibel */
                   1061:         j = pom / EG_STEP;         /* TL_TABLE steps */
                   1062: 
                   1063:         /* degree 0   -  90    , degree 180 -  90 : plus section */
                   1064:         SIN_TABLE[          s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
                   1065:         /* degree 180 - 270    , degree 360 - 270 : minus section */
                   1066:         SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT  -s] = &TL_TABLE[TL_MAX+j];
                   1067: /*      Log(LOG_INF,"sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP);*/
                   1068:     }
                   1069:     /* envelope counter -> envelope output table */
                   1070:     for (i=0; i<EG_ENT; i++)
                   1071:     {
                   1072:         /* ATTACK curve */
                   1073:         /* !!!!! preliminary !!!!! */
                   1074:         pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
                   1075:         /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
                   1076:         ENV_CURVE[i] = (int)pom;
                   1077:         /* DECAY ,RELEASE curve */
                   1078:         ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
                   1079: #ifdef SEG_SUPPORT
                   1080:         /* DECAY UPSIDE (SSG ENV) */
                   1081:         ENV_CURVE[(EG_UST>>ENV_BITS)+i]= EG_ENT-1-i;
                   1082: #endif
                   1083:     }
                   1084:     /* off */
                   1085:     ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
                   1086: 
                   1087:     /* decay to reattack envelope converttable */
                   1088:     j = EG_ENT-1;
                   1089:     for (i=0; i<EG_ENT; i++)
                   1090:     {
                   1091:         while( j && (ENV_CURVE[j] < i) ) j--;
                   1092:         DRAR_TABLE[i] = j<<ENV_BITS;
                   1093:         /* Log(LOG_INF,"DR %06X = %06X,AR=%06X\n",i,DRAR_TABLE[i],ENV_CURVE[DRAR_TABLE[i]>>ENV_BITS] ); */
                   1094:     }
                   1095:     return 1;
                   1096: }
                   1097: 
                   1098: 
                   1099: static void FMCloseTable( void )
                   1100: {
                   1101:     if( TL_TABLE ) free( TL_TABLE );
                   1102:     return;
                   1103: }
                   1104: 
                   1105: /* OPN/OPM Mode  Register Write */
                   1106: INLINE void FMSetMode( FM_ST *ST ,int n,int v )
                   1107: {
                   1108:     /* b7 = CSM MODE */
                   1109:     /* b6 = 3 slot mode */
                   1110:     /* b5 = reset b */
                   1111:     /* b4 = reset a */
                   1112:     /* b3 = timer enable b */
                   1113:     /* b2 = timer enable a */
                   1114:     /* b1 = load b */
                   1115:     /* b0 = load a */
                   1116:     ST->mode = v;
                   1117: 
                   1118:     /* reset Timer b flag */
                   1119:     if( v & 0x20 )
                   1120:         FM_STATUS_RESET(ST,0x02);
                   1121:     /* reset Timer a flag */
                   1122:     if( v & 0x10 )
                   1123:         FM_STATUS_RESET(ST,0x01);
                   1124:     /* load b */
                   1125:     if( v & 0x02 )
                   1126:     {
                   1127:         if( ST->TBC == 0 )
                   1128:         {
                   1129:             ST->TBC = ( 256-ST->TB)<<(4+12);
                   1130:             /* External timer handler */
                   1131:             if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,(double)ST->TBC,ST->TimerBase);
                   1132:         }
                   1133:     }else if (ST->timermodel == FM_TIMER_INTERVAL)
                   1134:     {   /* stop interbval timer */
                   1135:         if( ST->TBC != 0 )
                   1136:         {
                   1137:             ST->TBC = 0;
                   1138:             if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,0,ST->TimerBase);
                   1139:         }
                   1140:     }
                   1141:     /* load a */
                   1142:     if( v & 0x01 )
                   1143:     {
                   1144:         if( ST->TAC == 0 )
                   1145:         {
                   1146:             ST->TAC = (1024-ST->TA)<<12;
                   1147:             /* External timer handler */
                   1148:             if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,(double)ST->TAC,ST->TimerBase);
                   1149:         }
                   1150:     }else if (ST->timermodel == FM_TIMER_INTERVAL)
                   1151:     {   /* stop interbval timer */
                   1152:         if( ST->TAC != 0 )
                   1153:         {
                   1154:             ST->TAC = 0;
                   1155:             if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,0,ST->TimerBase);
                   1156:         }
                   1157:     }
                   1158: }
                   1159: 
                   1160: /* Timer A Overflow */
                   1161: INLINE void TimerAOver(FM_ST *ST)
                   1162: {
                   1163:     /* status set if enabled */
                   1164:     if(ST->mode & 0x04) FM_STATUS_SET(ST,0x01);
                   1165:     /* clear or reload the counter */
                   1166:     if (ST->timermodel == FM_TIMER_INTERVAL)
                   1167:     {
                   1168:         ST->TAC = (1024-ST->TA)<<12;
                   1169:         if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,0,(double)ST->TAC,ST->TimerBase);
                   1170:     }
                   1171:     else ST->TAC = 0;
                   1172: }
                   1173: /* Timer B Overflow */
                   1174: INLINE void TimerBOver(FM_ST *ST)
                   1175: {
                   1176:     /* status set if enabled */
                   1177:     if(ST->mode & 0x08) FM_STATUS_SET(ST,0x02);
                   1178:     /* clear or reload the counter */
                   1179:     if (ST->timermodel == FM_TIMER_INTERVAL)
                   1180:     {
                   1181:         ST->TBC = ( 256-ST->TB)<<4;
                   1182:         if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,1,(double)ST->TBC,ST->TimerBase);
                   1183:     }
                   1184:     else ST->TBC = 0;
                   1185: }
                   1186: /* CSM Key Controll */
                   1187: INLINE void CSMKeyControll(FM_CH *CH)
                   1188: {
                   1189:     int ksl = KSL[CH->kcode];
                   1190:     /* all key off */
                   1191:     FM_KEYOFF(CH,SLOT1);
                   1192:     FM_KEYOFF(CH,SLOT2);
                   1193:     FM_KEYOFF(CH,SLOT3);
                   1194:     FM_KEYOFF(CH,SLOT4);
                   1195:     /* total level latch */
                   1196:     CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + ksl;
                   1197:     CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + ksl;
                   1198:     CH->SLOT[SLOT3].TLL = CH->SLOT[SLOT3].TL + ksl;
                   1199:     CH->SLOT[SLOT4].TLL = CH->SLOT[SLOT4].TL + ksl;
                   1200:     /* all key on */
                   1201:     FM_KEYON(CH,SLOT1);
                   1202:     FM_KEYON(CH,SLOT2);
                   1203:     FM_KEYON(CH,SLOT3);
                   1204:     FM_KEYON(CH,SLOT4);
                   1205: }
                   1206: 
                   1207: #ifdef INTERNAL_TIMER
                   1208: /* ---------- calcrate timer A ---------- */
                   1209: INLINE void CALC_TIMER_A( FM_ST *ST , FM_CH *CSM_CH ){
                   1210:   if( ST->TAC &&  (ST->Timer_Handler==0) )
                   1211:     if( (ST->TAC -= ST->freqbase) <= 0 ){
                   1212:       TimerAOver( ST );
                   1213:       /* CSM mode key,TL controll */
                   1214:       if( ST->mode & 0x80 ){    /* CSM mode total level latch and auto key on */
                   1215:     CSMKeyControll( CSM_CH );
                   1216:       }
                   1217:     }
                   1218: }
                   1219: /* ---------- calcrate timer B ---------- */
                   1220: INLINE void CALC_TIMER_B( FM_ST *ST,int step){
                   1221:   if( ST->TBC && (ST->Timer_Handler==0) )
                   1222:     if( (ST->TBC -= ST->freqbase*step) <= 0 ){
                   1223:       TimerBOver( ST );
                   1224:     }
                   1225: }
                   1226: #endif /* INTERNAL_TIMER */
                   1227: 
                   1228: #if BUILD_OPN
                   1229: /* ---------- priscaler set(and make time tables) ---------- */
                   1230: void OPNSetPris(FM_OPN *OPN , int pris , int TimerPris, int SSGpris)
                   1231: {
                   1232:     int fn;
                   1233: 
                   1234:     /* frequency base */
                   1235:     OPN->ST.freqbase = (OPN->ST.rate) ? ((double)OPN->ST.clock * 4096.0 / OPN->ST.rate) / pris : 0;
                   1236:     /* Timer base time */
                   1237:     OPN->ST.TimerBase = (OPN->ST.rate) ? 1.0/((double)OPN->ST.clock / (double)TimerPris) : 0;
                   1238:     /* SSG part  priscaler set */
                   1239:     if( SSGpris ) SSGClk( OPN->ST.index, OPN->ST.clock * 2 / SSGpris );
                   1240:     /* make time tables */
                   1241:     init_timetables( &OPN->ST , OPN_DTTABLE , OPN_ARRATE , OPN_DRRATE );
                   1242:     /* make fnumber -> increment counter table */
                   1243:     for( fn=0 ; fn < 2048 ; fn++ )
                   1244:     {
                   1245:         /* it is freq table for octave 7 */
                   1246:         /* opn freq counter = 20bit */
                   1247:         OPN->FN_TABLE[fn] = (double)fn * OPN->ST.freqbase / 4096  * FREQ_RATE * (1<<7) / 2;
                   1248:     }
                   1249: /*  Log(LOG_INF,"OPN %d set priscaler %d\n",OPN->ST.index,pris);*/
                   1250: }
                   1251: 
                   1252: /* ---------- write a OPN mode register 0x20-0x2f ---------- */
                   1253: static void OPNWriteMode(FM_OPN *OPN, int r, int v)
                   1254: {
                   1255:     unsigned char c;
                   1256:     FM_CH *CH;
                   1257: 
                   1258:     switch(r){
                   1259:     case 0x21:  /* Test */
                   1260:         break;
                   1261:     case 0x22:  /* LFO FREQ (YM2608/YM2612) */
                   1262:         /* 3.98Hz,5.56Hz,6.02Hz,6.37Hz,6.88Hz,9.63Hz,48.1Hz,72.2Hz */
                   1263:         /* FM2608[n].LFOIncr = FM2608[n].LFO_TABLE[v&0x0f]; */
                   1264:         break;
                   1265:     case 0x24:  /* timer A High 8*/
                   1266:         OPN->ST.TA = (OPN->ST.TA & 0x03)|(((int)v)<<2);
                   1267:         break;
                   1268:     case 0x25:  /* timer A Low 2*/
                   1269:         OPN->ST.TA = (OPN->ST.TA & 0x3fc)|(v&3);
                   1270:         break;
                   1271:     case 0x26:  /* timer B */
                   1272:         OPN->ST.TB = v;
                   1273:         break;
                   1274:     case 0x27:  /* mode , timer controll */
                   1275:         FMSetMode( &(OPN->ST),OPN->ST.index,v );
                   1276:         break;
                   1277:     case 0x28:  /* key on / off */
                   1278:         c = v&0x03;
                   1279:         if( c == 3 ) break;
                   1280:         if( (v&0x04) && (OPN->type & TYPE_6CH) ) c+=3;
                   1281:         CH = OPN->P_CH;
                   1282:         CH = &CH[c];
                   1283:         /* csm mode */
                   1284:         if( c == 2 && (OPN->ST.mode & 0x80) ) break;
                   1285:         if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
                   1286:         if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
                   1287:         if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
                   1288:         if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
                   1289: /*      Log(LOG_INF,"OPN %d:%d : KEY %02X\n",n,c,v&0xf0);*/
                   1290:         break;
                   1291:     }
                   1292: }
                   1293: 
                   1294: /* ---------- write a OPN register (0x30-0xff) ---------- */
                   1295: static void OPNWriteReg(FM_OPN *OPN, int r, int v)
                   1296: {
                   1297:     unsigned char c;
                   1298:     FM_CH *CH;
                   1299:     FM_SLOT *SLOT;
                   1300: 
                   1301:     /* 0x30 - 0xff */
                   1302:     if( (c = OPN_CHAN(r)) == 3 ) return; /* 0xX3,0xX7,0xXB,0xXF */
                   1303:     if( (r >= 0x100) /* && (OPN->type & TYPE_6CH) */ ) c+=3;
                   1304:         CH = OPN->P_CH;
                   1305:         CH = &CH[c];
                   1306: 
                   1307:     SLOT = &(CH->SLOT[OPN_SLOT(r)]);
                   1308:     switch( r & 0xf0 ) {
                   1309:     case 0x30:  /* DET , MUL */
                   1310:         set_det_mul(&OPN->ST,CH,SLOT,v);
                   1311:         break;
                   1312:     case 0x40:  /* TL */
                   1313:         set_tl(CH,SLOT,v,(c == 2) && (OPN->ST.mode & 0x80) );
                   1314:         break;
                   1315:     case 0x50:  /* KS, AR */
                   1316:         set_ar_ksr(CH,SLOT,v,OPN->ST.AR_TABLE);
                   1317:         break;
                   1318:     case 0x60:  /*     DR */
                   1319:         /* bit7 = AMS ENABLE(YM2612) */
                   1320:         set_dr(SLOT,v,OPN->ST.DR_TABLE);
                   1321:         break;
                   1322:     case 0x70:  /*     SR */
                   1323:         set_sr(SLOT,v,OPN->ST.DR_TABLE);
                   1324:         break;
                   1325:     case 0x80:  /* SL, RR */
                   1326:         set_sl_rr(SLOT,v,OPN->ST.DR_TABLE);
                   1327:         break;
                   1328:     case 0x90:  /* SSG-EG */
                   1329: #ifndef SEG_SUPPORT
                   1330:         if(v&0x08) Log(LOG_ERR,"OPN %d,%d,%d :SSG-TYPE envelope selected (not supported )\n",OPN->ST.index,c,OPN_SLOT(r));
                   1331: #endif
                   1332:         SLOT->SEG = v&0x0f;
                   1333:         break;
                   1334:     case 0xa0:
                   1335:         switch( OPN_SLOT(r) ){
                   1336:         case 0:     /* 0xa0-0xa2 : FNUM1 */
                   1337:             {
                   1338:                 unsigned int fn  = (((unsigned int)( (CH->fn_h)&7))<<8) + v;
                   1339:                 unsigned char blk = CH->fn_h>>3;
                   1340:                 /* make keyscale code */
                   1341:                 CH->kcode = (blk<<2)|OPN_FKTABLE[(fn>>7)];
                   1342:                 /* make basic increment counter 32bit = 1 cycle */
                   1343:                 CH->fc = OPN->FN_TABLE[fn]>>(7-blk);
                   1344:                 CH->SLOT[SLOT1].Incr=-1;
                   1345:             }
                   1346:             break;
                   1347:         case 1:     /* 0xa4-0xa6 : FNUM2,BLK */
                   1348:             CH->fn_h = v&0x3f;
                   1349:             break;
                   1350:         case 2:     /* 0xa8-0xaa : 3CH FNUM1 */
                   1351:             if( r < 0x100)
                   1352:             {
                   1353:                 unsigned int fn  = (((unsigned int)(OPN->SL3.fn_h[c]&7))<<8) + v;
                   1354:                 unsigned char blk = OPN->SL3.fn_h[c]>>3;
                   1355:                 /* make keyscale code */
                   1356:                 OPN->SL3.kcode[c]= (blk<<2)|OPN_FKTABLE[(fn>>7)];
                   1357:                 /* make basic increment counter 32bit = 1 cycle */
                   1358:                 OPN->SL3.fc[c] = OPN->FN_TABLE[fn]>>(7-blk);
                   1359:                 (OPN->P_CH)[2].SLOT[SLOT1].Incr=-1;
                   1360:             }
                   1361:             break;
                   1362:         case 3:     /* 0xac-0xae : 3CH FNUM2,BLK */
                   1363:             if( r < 0x100)
                   1364:                 OPN->SL3.fn_h[c] = v&0x3f;
                   1365:             break;
                   1366:         }
                   1367:         break;
                   1368:     case 0xb0:
                   1369:         switch( OPN_SLOT(r) ){
                   1370:         case 0:     /* 0xb0-0xb2 : FB,ALGO */
                   1371:             {
                   1372:                 int feedback = (v>>3)&7;
                   1373:                 CH->ALGO = v&7;
                   1374:                 CH->FB   = feedback ? 8 - feedback : 0;
                   1375:                 set_algorythm( CH );
                   1376:             }
                   1377:             break;
                   1378:         case 1:     /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2608) */
                   1379:             if( OPN->type & TYPE_LFOPAN)
                   1380:             {
                   1381:                 /* b0-2 PMS */
                   1382:                 /* 0,3.4,6.7,10,14,20,40,80(cent) */
                   1383:                 SLOT->pms = (v>>4) & 0x07;
                   1384:                 /* b4-5 AMS */
                   1385:                 /* 0,1.4,5.9,11.8(dB) */
                   1386:                 SLOT->ams = v & 0x03;
                   1387:                 /* PAN */
                   1388:                 CH->PAN = (v>>6)&0x03; /* PAN : b6 = R , b7 = L */
                   1389:                 set_algorythm( CH );
                   1390:                 /* Log(LOG_INF,"OPN %d,%d : PAN %d\n",n,c,CH->PAN);*/
                   1391:             }
                   1392:             break;
                   1393:         }
                   1394:         break;
                   1395:     }
                   1396: }
                   1397: 
                   1398: #endif /* BUILD_OPN */
                   1399: 
                   1400: #if BUILD_YM2203
                   1401: /*******************************************************************************/
                   1402: /*      YM2203 local section                                                   */
                   1403: /*******************************************************************************/
                   1404: static YM2203 *FM2203=NULL; /* array of YM2203's */
                   1405: 
                   1406: /* ---------- update one of chip ----------- */
                   1407: void YM2203UpdateOne(int num, void *buffer, int length)
                   1408: {
                   1409:     YM2203 *F2203 = &(FM2203[num]);
                   1410:     FM_OPN *OPN =   &(FM2203[num].OPN);
                   1411:     int i,ch;
                   1412:     int data;
                   1413:     FMSAMPLE *buf = (FMSAMPLE *)buffer;
                   1414: 
                   1415:     State = &F2203->OPN.ST;
                   1416:     cch[0]   = &F2203->CH[0];
                   1417:     cch[1]   = &F2203->CH[1];
                   1418:     cch[2]   = &F2203->CH[2];
                   1419: 
                   1420:     /* frequency counter channel A */
                   1421:     CALC_FCOUNT( cch[0] );
                   1422:     /* frequency counter channel B */
                   1423:     CALC_FCOUNT( cch[1] );
                   1424:     /* frequency counter channel C */
                   1425:     if( (State->mode & 0xc0) ){
                   1426:         /* 3SLOT MODE */
                   1427:         if( cch[2]->SLOT[SLOT1].Incr==-1){
                   1428:             /* 3 slot mode */
                   1429:             CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
                   1430:             CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
                   1431:             CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
                   1432:             CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
                   1433:         }
                   1434:     }else CALC_FCOUNT( cch[2] );
                   1435: 
                   1436:     for( i=0; i < length ; i++ )
                   1437:     {
                   1438:         /*            channel A         channel B         channel C      */
                   1439:         outd[OPN_CENTER] = 0;
                   1440:         /* calcrate FM */
                   1441:         for( ch=0;ch<3;ch++) FM_CALC_CH( cch[ch] );
                   1442:         /* limit check */
                   1443:         data = Limit( outd[OPN_CENTER] , OPN_MAXOUT, OPN_MINOUT );
                   1444:         /* store to sound buffer */
                   1445:         buf[i] = data >> OPN_OUTSB;
                   1446: #ifdef INTERNAL_TIMER
                   1447:         /* timer controll */
                   1448:         CALC_TIMER_A( State , cch[2] );
                   1449: #endif
                   1450:     }
                   1451: #ifdef INTERNAL_TIMER
                   1452:     CALC_TIMER_B( State , length );
                   1453: #endif
                   1454: }
                   1455: 
                   1456: /* ---------- reset one of chip ---------- */
                   1457: void YM2203ResetChip(int num)
                   1458: {
                   1459:     int i;
                   1460:     FM_OPN *OPN = &(FM2203[num].OPN);
                   1461: 
                   1462:     /* Reset Priscaler */
                   1463:     OPNSetPris( OPN , 6*12 , 6*12 ,4); /* 1/6 , 1/4 */
                   1464:     /* reset SSG section */
                   1465:     SSGReset(OPN->ST.index);
                   1466:     /* status clear */
                   1467:     FM_IRQMASK_SET(&OPN->ST,0x03);
                   1468:     OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
                   1469:     reset_channel( &OPN->ST , FM2203[num].CH , 3 );
                   1470:     /* reset OPerator paramater */
                   1471:     for(i = 0xb6 ; i >= 0xb4 ; i-- ) OPNWriteReg(OPN,i,0xc0); /* PAN RESET */
                   1472:     for(i = 0xb2 ; i >= 0x30 ; i-- ) OPNWriteReg(OPN,i,0);
                   1473:     for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
                   1474: }
                   1475: #if 0
                   1476: /* ---------- return the buffer ---------- */
                   1477: FMSAMPLE *YM2203Buffer(int n)
                   1478: {
                   1479:     return FM2203[n].Buf;
                   1480: }
                   1481: 
                   1482: /* ---------- set buffer ---------- */
                   1483: int YM2203SetBuffer(int n, FMSAMPLE *buf)
                   1484: {
                   1485:     if( buf == 0 ) return -1;
                   1486:     FM2203[n].Buf = buf;
                   1487:     return 0;
                   1488: }
                   1489: #endif
                   1490: 
                   1491: /* ----------  Initialize YM2203 emulator(s) ----------    */
                   1492: /* 'num' is the number of virtual YM2203's to allocate     */
                   1493: /* 'rate' is sampling rate and 'bufsiz' is the size of the */
                   1494: /* buffer that should be updated at each interval          */
                   1495: int YM2203Init(int num, int clock, int rate,
                   1496:                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
                   1497: {
                   1498:     int i;
                   1499: 
                   1500:     if (FM2203) return (-1);    /* duplicate init. */
                   1501:     cur_chip = NULL;    /* hiro-shi!! */
                   1502: 
                   1503:     FMNumChips = num;
                   1504: 
                   1505:     /* allocate ym2203 state space */
                   1506:     if( (FM2203 = (YM2203 *)malloc(sizeof(YM2203) * FMNumChips))==NULL)
                   1507:         return (-1);
                   1508:     /* clear */
                   1509:     memset(FM2203,0,sizeof(YM2203) * FMNumChips);
                   1510:     /* allocate total level table (128kb space) */
                   1511:     if( !FMInitTable() )
                   1512:     {
                   1513:         free( FM2203 );
                   1514:         return (-1);
                   1515:     }
                   1516: 
                   1517:     for ( i = 0 ; i < FMNumChips; i++ ) {
                   1518:         FM2203[i].OPN.ST.index = i;
                   1519:         FM2203[i].OPN.type = TYPE_YM2203;
                   1520:         FM2203[i].OPN.P_CH = FM2203[i].CH;
                   1521:         FM2203[i].OPN.ST.clock = clock;
                   1522:         FM2203[i].OPN.ST.rate = rate;
                   1523:         /* FM2203[i].OPN.ST.irq = 0; */
                   1524:         /* FM2203[i].OPN.ST.satus = 0; */
                   1525:         FM2203[i].OPN.ST.timermodel = FM_TIMER_SINGLE;
                   1526:         /* Extend handler */
                   1527:         FM2203[i].OPN.ST.Timer_Handler = TimerHandler;
                   1528:         FM2203[i].OPN.ST.IRQ_Handler   = IRQHandler;
                   1529:         YM2203ResetChip(i);
                   1530:     }
                   1531:     return(0);
                   1532: }
                   1533: 
                   1534: /* ---------- shut down emurator ----------- */
                   1535: void YM2203Shutdown(void)
                   1536: {
                   1537:     if (!FM2203) return;
                   1538: 
                   1539:     FMCloseTable();
                   1540:     free(FM2203);
                   1541:     FM2203 = NULL;
                   1542: }
                   1543: 
                   1544: /* ---------- YM2203 I/O interface ---------- */
                   1545: int YM2203Write(int n,int a,int v)
                   1546: {
                   1547:     FM_OPN *OPN = &(FM2203[n].OPN);
                   1548: 
                   1549:     if( !(a&1) )
                   1550:     {   /* address port */
                   1551:         OPN->ST.address = v & 0xff;
                   1552:         /* Write register to SSG emurator */
                   1553:         if( v < 16 ) SSGWrite(n,0,v);
                   1554:         switch(OPN->ST.address)
                   1555:         {
                   1556:         case 0x2d:  /* divider sel */
                   1557:             OPNSetPris( OPN, 6*12, 6*12 ,4); /* OPN 1/6 , SSG 1/4 */
                   1558:             break;
                   1559:         case 0x2e:  /* divider sel */
                   1560:             OPNSetPris( OPN, 3*12, 3*12,2); /* OPN 1/3 , SSG 1/2 */
                   1561:             break;
                   1562:         case 0x2f:  /* divider sel */
                   1563:             OPNSetPris( OPN, 2*12, 2*12,1); /* OPN 1/2 , SSG 1/1 */
                   1564:             break;
                   1565:         }
                   1566:     }
                   1567:     else
                   1568:     {   /* data port */
                   1569:         int addr = OPN->ST.address;
                   1570:         switch( addr & 0xf0 )
                   1571:         {
                   1572:         case 0x00:  /* 0x00-0x0f : SSG section */
                   1573:             /* Write data to SSG emurator */
                   1574:             SSGWrite(n,a,v);
                   1575:             break;
                   1576:         case 0x20:  /* 0x20-0x2f : Mode section */
                   1577:             YM2203UpdateReq(n);
                   1578:             /* write register */
                   1579:              OPNWriteMode(OPN,addr,v);
                   1580:             break;
                   1581:         default:    /* 0x30-0xff : OPN section */
                   1582:             YM2203UpdateReq(n);
                   1583:             /* write register */
                   1584:              OPNWriteReg(OPN,addr,v);
                   1585:         }
                   1586:     }
                   1587:     return OPN->ST.irq;
                   1588: }
                   1589: 
                   1590: unsigned char YM2203Read(int n,int a)
                   1591: {
                   1592:     YM2203 *F2203 = &(FM2203[n]);
                   1593:     int addr = F2203->OPN.ST.address;
                   1594:     int ret = 0;
                   1595: 
                   1596:     if( !(a&1) )
                   1597:     {   /* status port */
                   1598:         ret = F2203->OPN.ST.status;
                   1599:     }
                   1600:     else
                   1601:     {   /* data port (ONLY SSG) */
                   1602:         if( addr < 16 ) ret = SSGRead(n);
                   1603:     }
                   1604:     return ret;
                   1605: }
                   1606: 
                   1607: int YM2203TimerOver(int n,int c)
                   1608: {
                   1609:     YM2203 *F2203 = &(FM2203[n]);
                   1610: 
                   1611:     if( c )
                   1612:     {   /* Timer B */
                   1613:         TimerBOver( &(F2203->OPN.ST) );
                   1614:     }
                   1615:     else
                   1616:     {   /* Timer A */
                   1617:         YM2203UpdateReq(n);
                   1618:         /* timer update */
                   1619:         TimerAOver( &(F2203->OPN.ST) );
                   1620:         /* CSM mode key,TL controll */
                   1621:         if( F2203->OPN.ST.mode & 0x80 )
                   1622:         {   /* CSM mode total level latch and auto key on */
                   1623:             CSMKeyControll( &(F2203->CH[2]) );
                   1624:         }
                   1625:     }
                   1626:     return F2203->OPN.ST.irq;
                   1627: }
                   1628: 
                   1629: #endif /* BUILD_YM2203 */
                   1630: 
                   1631: #if (BUILD_FM_ADPCMA || BUILD_FM_ADPCMB)
                   1632: 
                   1633: /*#define ADPCMA_DECODE_RANGE 1024 */
                   1634: #define ADPCMA_DECODE_RANGE 1024
                   1635: #define ADPCMA_DECODE_MIN (-(ADPCMA_DECODE_RANGE*ADPCMA_VOLUME_RATE))
                   1636: #define ADPCMA_DECODE_MAX ((ADPCMA_DECODE_RANGE*ADPCMA_VOLUME_RATE)-1)
                   1637: #define ADPCMA_VOLUME_DIV 1
                   1638: 
                   1639: #define ADPCMB_DECODE_RANGE 32768
                   1640: #define ADPCMB_DECODE_MIN (-(ADPCMB_DECODE_RANGE))
                   1641: #define ADPCMB_DECODE_MAX ((ADPCMB_DECODE_RANGE)-1)
                   1642: 
                   1643: /* DELTA-T particle adjuster */
                   1644: #define ADPCMB_DELTA_MAX (24576)
                   1645: #define ADPCMB_DELTA_MIN (127)
                   1646: #define ADPCMB_DELTA_DEF (127)
                   1647: 
                   1648: /***************************************************************/
                   1649: /*    ADPCM units are made by Hiromitsu Shioya (MMSND)         */
                   1650: /***************************************************************/
                   1651: 
                   1652: static char         *pcmbufA, *pcmbufB;
                   1653: static unsigned int pcmsizeA, pcmsizeB;
                   1654: 
                   1655: static unsigned char adpcm_arrivedEndAddress;
                   1656: static unsigned char adpcm_statusmask;
                   1657: 
                   1658: /************************************************************/
                   1659: /************************************************************/
                   1660: /* --------------------- subroutines  --------------------- */
                   1661: /************************************************************/
                   1662: /************************************************************/
                   1663: /************************/
                   1664: /*    ADPCM A tables    */
                   1665: /************************/
                   1666: static int jedi_table[49*16];
                   1667: static int decode_tableA1[16] = {
                   1668:   -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16,
                   1669:   -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16
                   1670: };
                   1671: 
                   1672: /* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */
                   1673: /* 8 = -1 , 2 5 8 11 */
                   1674: /* 9 = -1 , 2 5 9 13 */
                   1675: /* 10= -1 , 2 6 10 14 */
                   1676: /* 12= -1 , 2 7 12 17 */
                   1677: /* 20= -2 , 4 12 20 32 */
                   1678: 
                   1679: #if 1
                   1680: static void InitOPNB_ADPCMATable(void){
                   1681:     int step, nib;
                   1682: 
                   1683:     for (step = 0; step <= 48; step++)
                   1684:     {
                   1685:         int stepval = floor (16.0 * pow (11.0 / 10.0, (double)step) * ADPCMA_VOLUME_RATE);
                   1686:         /* loop over all nibbles and compute the difference */
                   1687:         for (nib = 0; nib < 16; nib++)
                   1688:         {
                   1689:             int value = stepval*((nib&0x07)*2+1)/8;
                   1690:             jedi_table[step*16+nib] = (nib&0x08) ? -value : value;
                   1691:         }
                   1692:     }
                   1693: }
                   1694: #else
                   1695: static int decode_tableA2[49] = {
                   1696:   0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001c, 0x001f,
                   1697:   0x0022, 0x0025, 0x0029, 0x002d, 0x0032, 0x0037, 0x003c, 0x0042,
                   1698:   0x0049, 0x0050, 0x0058, 0x0061, 0x006b, 0x0076, 0x0082, 0x008f,
                   1699:   0x009d, 0x00ad, 0x00be, 0x00d1, 0x00e6, 0x00fd, 0x0117, 0x0133,
                   1700:   0x0151, 0x0173, 0x0198, 0x01c1, 0x01ee, 0x0220, 0x0256, 0x0292,
                   1701:   0x02d4, 0x031c, 0x036c, 0x03c3, 0x0424, 0x048e, 0x0502, 0x0583,
                   1702:   0x0610
                   1703: };
                   1704: static void InitOPNB_ADPCMATable(void){
                   1705:    int ta,tb,tc;
                   1706:    for(ta=0;ta<49;ta++){
                   1707:      for(tb=0;tb<16;tb++){
                   1708:        tc=0;
                   1709:        if(tb&0x04){tc+=((decode_tableA2[ta]*ADPCMA_VOLUME_RATE));}
                   1710:        if(tb&0x02){tc+=((decode_tableA2[ta]*ADPCMA_VOLUME_RATE)>>1);}
                   1711:        if(tb&0x01){tc+=((decode_tableA2[ta]*ADPCMA_VOLUME_RATE)>>2);}
                   1712:        tc+=((decode_tableA2[ta]*ADPCMA_VOLUME_RATE)>>3);
                   1713:        if(tb&0x08){tc=(0-tc);}
                   1714:        jedi_table[ta*16+tb]=tc;
                   1715:      }
                   1716:    }
                   1717: }
                   1718: #endif
                   1719: 
                   1720: /************************/
                   1721: /*    ADPCM B tables    */
                   1722: /************************/
                   1723: /* Forecast to next Forecast (rate = *8) */
                   1724: /* 1/8 , 3/8 , 5/8 , 7/8 , 9/8 , 11/8 , 13/8 , 15/8 */
                   1725: static const int decode_tableB1[16] = {
                   1726:   1,   3,   5,   7,   9,  11,  13,  15,
                   1727:   -1,  -3,  -5,  -7,  -9, -11, -13, -15,
                   1728: };
                   1729: /* delta to next delta (rate= *64) */
                   1730: /* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */
                   1731: static const int decode_tableB2[16] = {
                   1732:   57,  57,  57,  57, 77, 102, 128, 153,
                   1733:   57,  57,  57,  57, 77, 102, 128, 153
                   1734: };
                   1735: 
                   1736: /* Forecast to Measurement (rate = *8) */
                   1737: /*      n < 1/4 , 1/4 <= n > 1/2 , 1/2 <= n > 3/4 , 3/4 <= n > 1 */
                   1738: /* 1 <= n > 5/4 , 5/4 <= n > 3/2 , 3/2 <= n > 7/4 , 7/4 <= n     */
                   1739: #if 1
                   1740: #define decode_tableB3 decode_tableB1
                   1741: #else
                   1742: static const int decode_tableB3[16] = {
                   1743:   0, 2,  4,  6,  8,  10, 12, 14,
                   1744:   0,-2, -4, -6, -8, -10,-12,-14
                   1745: };
                   1746: #endif
                   1747: 
                   1748: /**** ADPCM A (Non control type) ****/
                   1749: INLINE void OPNB_ADPCM_CALC_CHA( YM2610 *F2610, ADPCM_CH *ch )
                   1750: {
                   1751:     unsigned int step;
                   1752:     int data;
                   1753: 
                   1754:     ch->now_step += ch->step;
                   1755:     if ( ch->now_step >= (1<<ADPCM_SHIFT) )
                   1756:     {
                   1757:         step = ch->now_step >> ADPCM_SHIFT;
                   1758:         ch->now_step &= (1<<ADPCM_SHIFT)-1;
                   1759:         /* end check */
                   1760:         if ( (ch->now_addr+step) > (ch->end<<1) ) {
                   1761:             ch->flag = 0;
                   1762:             F2610->adpcm_arrivedEndAddress |= ch->flagMask & F2610->adpcm_statusmask;
                   1763:             return;
                   1764:         }
                   1765:         do{
                   1766: #if 0
                   1767:             if ( ch->now_addr > (pcmsizeA<<1) ) {
                   1768:                 Log(LOG_WAR,"YM2610: Attempting to play past adpcm rom size!\n" );
                   1769:                 return;
                   1770:             }
                   1771: #endif
                   1772:             if( ch->now_addr&1 ) data = ch->now_data & 0x0f;
                   1773:             else
                   1774:             {
                   1775:                 ch->now_data = *(pcmbufA+(ch->now_addr>>1));
                   1776:                 data = (ch->now_data >> 4)&0x0f;
                   1777:             }
                   1778:             ch->now_addr++;
                   1779: 
                   1780:             ch->adpcmx = Limit( ch->adpcmx + (jedi_table[ch->adpcmd+data]),
                   1781:                         ADPCMA_DECODE_MAX, ADPCMA_DECODE_MIN );
                   1782:             ch->adpcmd = Limit( ch->adpcmd + decode_tableA1[data], 48*16, 0*16 );
                   1783:             /**** calc pcm * volume data ****/
                   1784:             ch->adpcml = ch->adpcmx * ch->volume;
                   1785:         }while(--step);
                   1786:     }
                   1787:     /* output for work of output channels (outd[OPNxxxx])*/
                   1788:     *(ch->pan) += ch->adpcml;
                   1789: }
                   1790: 
                   1791: /**** ADPCM B (Delta-T control type) ****/
                   1792: INLINE void OPNB_ADPCM_CALC_CHB( YM2610 *F2610, ADPCM_CH *ch )
                   1793: {
                   1794:     unsigned int step;
                   1795:     int data;
                   1796: 
                   1797:     int old_m;
                   1798:     int now_leveling;
                   1799:     int delta_next;
                   1800: 
                   1801:     ch->now_step += ch->step;
                   1802:     if ( ch->now_step >= (1<<ADPCM_SHIFT) )
                   1803:     {
                   1804:         step = ch->now_step >> ADPCM_SHIFT;
                   1805:         ch->now_step &= (1<<ADPCM_SHIFT)-1;
                   1806:         do{
                   1807:             if ( ch->now_addr > (ch->end<<1) ) {
                   1808:                 if( F2610->port0state&0x10 ){
                   1809:                     /**** repeat start ****/
                   1810:                     ch->now_addr = ch->start<<1;
                   1811:                     /*ch->adpcmm   = 0;*/
                   1812:                     ch->adpcmx   = 0;
                   1813:                     /* ch->adpcml   = 0; */
                   1814:                     ch->adpcmd   = ADPCMB_DELTA_DEF;
                   1815:                     ch->next_leveling = 0;
                   1816:                     ch->flag     = 1;
                   1817:                 }else{
                   1818:                     F2610->adpcm_arrivedEndAddress |= ch->flagMask & F2610->adpcm_statusmask;
                   1819:                     ch->flag = 0;
                   1820:                     ch->adpcml = 0;
                   1821:                     now_leveling = 0;
                   1822:                     return;
                   1823:                 }
                   1824:             }
                   1825: #if 0
                   1826:             if ( ch->now_addr > (pcmsizeB<<1) ) {
                   1827:                 Log(LOG_WAR,"YM2610: Attempting to play past Delta T rom size!\n" );
                   1828:                 return;
                   1829:             }
                   1830: #endif
                   1831:             if( ch->now_addr&1 ) data = ch->now_data & 0x0f;
                   1832:             else
                   1833:             {
                   1834:                 ch->now_data = *(pcmbufB+(ch->now_addr>>1));
                   1835:                 data = ch->now_data >> 4;
                   1836:             }
                   1837:             ch->now_addr++;
                   1838:             /* shift Measurement value */
                   1839:             old_m      = ch->adpcmx/*adpcmm*/;
                   1840:             /* ch->adpcmm = Limit( ch->adpcmx + (decode_tableB3[data] * ch->adpcmd / 8) ,ADPCMB_DECODE_MAX, ADPCMB_DECODE_MIN ); */
                   1841:             /* Forecast to next Forecast */
                   1842:             ch->adpcmx = Limit( ch->adpcmx+(decode_tableB1[data] * ch->adpcmd / 8) ,ADPCMB_DECODE_MAX, ADPCMB_DECODE_MIN );
                   1843:             /* delta to next delta */
                   1844:             ch->adpcmd = Limit( ( ch->adpcmd * decode_tableB2[data] ) / 64, ADPCMB_DELTA_MAX, ADPCMB_DELTA_MIN );
                   1845:             /* shift leveling value */
                   1846:             delta_next        = ch->adpcmx/*adpcmm*/ - old_m;
                   1847:             now_leveling      = ch->next_leveling;
                   1848:             ch->next_leveling = old_m + (delta_next / 2);
                   1849:         }while(--step);
                   1850: /*#define CUT_RE_SAMPLING */
                   1851: #ifdef CUT_RE_SAMPLING
                   1852:         ch->adpcml  = ch->next_leveling * ch->volume;
                   1853:         ch->adpcml  = ch->adpcmx/*adpcmm*/ * ch->volume;
                   1854:     }
                   1855: #else
                   1856:         /* delta step of re-sampling */
                   1857:         ch->sample_step = (ch->next_leveling - now_leveling) * ch->volume_w_step;
                   1858:         /* output of start point */
                   1859:         ch->adpcml  = now_leveling * ch->volume;
                   1860:         /* adjust to now */
                   1861:         ch->adpcml += (int)((double)ch->sample_step * ((double)ch->now_step/(double)ch->step));
                   1862:     }
                   1863:     ch->adpcml += ch->sample_step;
                   1864: #endif
                   1865:     /* output for work of output channels (outd[OPNxxxx])*/
                   1866:     /**(ch->pan) += ch->adpcml; */
                   1867:     *(ch->pan) += ch->adpcml;
                   1868: }
                   1869: 
                   1870: static YM2610 *FM2610=NULL; /* array of YM2610's */
                   1871: 
                   1872: /* ADPCM type A */
                   1873: static void FM_ADPCMAWrite(YM2610 *F2610,int r,int v)
                   1874: {
                   1875:     ADPCM_CH *adpcm = F2610->adpcm;
                   1876:     unsigned char c = r&0x07;
                   1877: 
                   1878:     F2610->adpcmreg[1][r] = v&0xff; /* stock data */
                   1879:     switch( r ){
                   1880:     case 0x00: /* DM,--,C5,C4,C3,C2,C1,C0 */
                   1881:       F2610->port1state = v&0xff;
                   1882:       if( !(v&0x80) ){
                   1883:         /* KEY ON */
                   1884:         for( c = 0; c < 6; c++ ){
                   1885:           if( (1<<c)&v ){
                   1886:         /**** start adpcm ****/
                   1887:         adpcm[c].step     = (unsigned int)((float)(1<<ADPCM_SHIFT)*((float)F2610->OPN.ST.freqbase)/4096.0/3.0);
                   1888:         adpcm[c].now_addr = adpcm[c].start<<1;
                   1889:         adpcm[c].now_step = (1<<ADPCM_SHIFT)-adpcm[c].step;
                   1890:         /*adpcm[c].adpcmm   = 0;*/
                   1891:         adpcm[c].adpcmx   = 0;
                   1892:         adpcm[c].adpcmd   = 0;
                   1893:         adpcm[c].adpcml   = 0;
                   1894:         adpcm[c].flag     = 1;
                   1895:         if(F2610->pcmbuf[1]==NULL){         /* Check ROM Mapped */
                   1896: #ifdef __RAINE__
                   1897:           PrintDebug("YM2610: main adpcm rom not mapped\n");
                   1898: #else
                   1899:           Log(LOG_WAR,"YM2610: Attempting to play regular adpcm but no rom is mapped\n");
                   1900: #endif
                   1901:           adpcm[c].flag = 0;
                   1902:         } else{
                   1903:           if(adpcm[c].end >= F2610->pcm_size[1]){       /* Check End in Range */
                   1904: #ifdef __RAINE__
                   1905:             PrintDebug("YM2610: main adpcm end out of range: $%08x\n",adpcm[c].end);
                   1906: #endif
                   1907:             adpcm[c].end = F2610->pcm_size[1]-1;
                   1908:           }
                   1909:           if(adpcm[c].start >= F2610->pcm_size[1]){ /* Check Start in Range */
                   1910: #ifdef __RAINE__
                   1911:             PrintDebug("YM2610: main adpcm start out of range: $%08x\n",adpcm[c].start);
                   1912: #endif
                   1913:             adpcm[c].flag = 0;
                   1914:           }
                   1915:         }
                   1916:         /*** (1<<c)&v ***/
                   1917:           }
                   1918:           /**** for loop ****/
                   1919:         }
                   1920:       } else{
                   1921:         /* KEY OFF */
                   1922:         for( c = 0; c < 6; c++ ){
                   1923:           if( (1<<c)&v )  adpcm[c].flag = 0;
                   1924:         }
                   1925:       }
                   1926:       break;
                   1927:     case 0x01:  /* B0-5 = TL 0.75dB step */
                   1928:         F2610->TL_adpcmb = &(TL_TABLE[((v&0x3f)^0x3f)*(int)(0.75/EG_STEP)]);
                   1929:         for( c = 0; c < 6; c++ ){
                   1930:           adpcm[c].volume = F2610->TL_adpcmb[adpcm[c].IL*(int)(0.75/EG_STEP)] / ADPCMA_DECODE_RANGE / ADPCMA_VOLUME_DIV;
                   1931:           /**** calc pcm * volume data ****/
                   1932:           adpcm[c].adpcml = adpcm[c].adpcmx * adpcm[c].volume;
                   1933:         }
                   1934:         break;
                   1935:     default:
                   1936:         c = r&0x07;
                   1937:         if( c >= 0x06 ) return;
                   1938:         switch( r&0x38 ){
                   1939:         case 0x08:  /* B7=L,B6=R,B4-0=IL */
                   1940:             adpcm[c].IL = (v&0x1f)^0x1f;
                   1941:             adpcm[c].volume = F2610->TL_adpcmb[adpcm[c].IL*(int)(0.75/EG_STEP)] / ADPCMA_DECODE_RANGE / ADPCMA_VOLUME_DIV;
                   1942:             adpcm[c].pan    = &outd[(v>>6)&0x03];
                   1943:             /**** calc pcm * volume data ****/
                   1944:             adpcm[c].adpcml = adpcm[c].adpcmx * adpcm[c].volume;
                   1945:             break;
                   1946:         case 0x10:
                   1947:         case 0x18:
                   1948:             adpcm[c].start  = ( (F2610->adpcmreg[1][0x18 + c]*0x0100 | F2610->adpcmreg[1][0x10 + c]) << F2610->port1shift);
                   1949:             break;
                   1950:         case 0x20:
                   1951:         case 0x28:
                   1952:             adpcm[c].end    = ( (F2610->adpcmreg[1][0x28 + c]*0x0100 | F2610->adpcmreg[1][0x20 + c]) << F2610->port1shift);
                   1953:             adpcm[c].end   += (1<<F2610->port1shift) - 1;
                   1954:             break;
                   1955:         }
                   1956:     }
                   1957: }
                   1958: 
                   1959: /* ADPCM type B (DELTA-T) */
                   1960: static void FM_ADPCMBWrite(YM2610 *F2610,int r,int v)
                   1961: {
                   1962:     ADPCM_CH *adpcm = &(F2610->adpcm[6]);
                   1963: 
                   1964:     F2610->adpcmreg[0][r] = v&0xff; /* stock data */
                   1965:     switch( r ){
                   1966:     case 0x00:  /* START,REC,MEMDATA,REPEAT,SPOFF,--,--,RESET */
                   1967: #if 0
                   1968:         case 0x60:  /* write buffer MEMORY from PCM data port */
                   1969:         case 0x20:  /* read  buffer MEMORY to   PCM data port */
                   1970: #endif
                   1971:       if( v&0x80 ){
                   1972:         F2610->port0state = v&0x90; /* start req,memory mode,repeat flag copy */
                   1973:         /**** start ADPCM ****/
                   1974:         adpcm->volume_w_step = (double)adpcm->volume * adpcm->step / (1<<ADPCM_SHIFT);
                   1975:         adpcm->now_addr = (adpcm->start)<<1;
                   1976:         adpcm->now_step = (1<<ADPCM_SHIFT)-adpcm->step;
                   1977:         /*adpcm->adpcmm   = 0;*/
                   1978:         adpcm->adpcmx   = 0;
                   1979:         adpcm->adpcml   = 0;
                   1980:         adpcm->adpcmd   = ADPCMB_DELTA_DEF;
                   1981:         adpcm->next_leveling=0;
                   1982:         adpcm->flag     = 1; /* start ADPCM */
                   1983:         if( !adpcm->step ){
                   1984:           adpcm->flag = 0;
                   1985:           F2610->port0state = 0x00;
                   1986:         }
                   1987:         /**** PCMROM check & limit check ****/
                   1988:         if(F2610->pcmbuf[0] == NULL){           /* Check ROM Mapped */
                   1989: #ifdef __RAINE__
                   1990:           PrintDebug("YM2610: Delta-T adpcm rom not mapped\n");
                   1991: #endif
                   1992:           adpcm->flag = 0;
                   1993:           F2610->port0state = 0x00;
                   1994:         } else{
                   1995:           if( adpcm->end >= F2610->pcm_size[0] ){       /* Check End in Range */
                   1996: #ifdef __RAINE__
                   1997:         PrintDebug("YM2610: Delta-T adpcm end out of range: $%08x\n",adpcm->end);
                   1998: #endif
                   1999:         adpcm->end = F2610->pcm_size[0] - 1;
                   2000:           }
                   2001:           if( adpcm->start >= F2610->pcm_size[0] ){     /* Check Start in Range */
                   2002: #ifdef __RAINE__
                   2003:         PrintDebug("YM2610: Delta-T adpcm start out of range: $%08x\n",adpcm->start);
                   2004: #endif
                   2005:         adpcm->flag = 0;
                   2006:         F2610->port0state = 0x00;
                   2007:           }
                   2008:         }
                   2009:       } else if( v&0x01 ){
                   2010:         adpcm->flag = 0;
                   2011:         F2610->port0state = 0x00;
                   2012:       }
                   2013:       break;
                   2014:     case 0x01:  /* L,R,-,-,SAMPLE,DA/AD,RAMTYPE,ROM */
                   2015:       F2610->port0control = v&0xff;
                   2016:       adpcm->pan = &outd[(v>>6)&0x03];
                   2017:       break;
                   2018:     case 0x02:  /* Start Address L */
                   2019:     case 0x03:  /* Start Address H */
                   2020:       adpcm->start  = (F2610->adpcmreg[0][0x3]*0x0100 | F2610->adpcmreg[0][0x2]) << F2610->port0shift;
                   2021:         break;
                   2022:     case 0x04:  /* Stop Address L */
                   2023:     case 0x05:  /* Stop Address H */
                   2024:         adpcm->end    = (F2610->adpcmreg[0][0x5]*0x0100 | F2610->adpcmreg[0][0x4]) << F2610->port0shift;
                   2025:         adpcm->end   += (1<<F2610->port0shift) - 1;
                   2026:         break;
                   2027:     case 0x06:  /* Prescale L (PCM and Recoard frq) */
                   2028:     case 0x07:  /* Proscale H */
                   2029:     case 0x08:  /* ADPCM data */
                   2030:       break;
                   2031:     case 0x09:  /* DELTA-N L (ADPCM Playback Prescaler) */
                   2032:     case 0x0a:  /* DELTA-N H */
                   2033:         adpcm->delta  = (F2610->adpcmreg[0][0xa]*0x0100 | F2610->adpcmreg[0][0x9]);
                   2034:         adpcm->step     = (unsigned int)((float)(adpcm->delta*(1<<(ADPCM_SHIFT-16)))*((float)F2610->OPN.ST.freqbase)/4096.0);
                   2035:         adpcm->volume_w_step = (double)adpcm->volume * adpcm->step / (1<<ADPCM_SHIFT);
                   2036:         break;
                   2037:     case 0x0b:  /* Level control (volume , voltage flat) */
                   2038:         {
                   2039:             int oldvol = adpcm->volume;
                   2040:             adpcm->volume = ((v&0xff)<<(TL_BITS-8)) * ADPCMB_VOLUME_RATE / ADPCMB_DECODE_RANGE;
                   2041:             if( oldvol != 0 )
                   2042:             {
                   2043:                 adpcm->adpcml      = (int)((double)adpcm->adpcml      / (double)oldvol * (double)adpcm->volume);
                   2044:                 adpcm->sample_step = (int)((double)adpcm->sample_step / (double)oldvol * (double)adpcm->volume);
                   2045:             }
                   2046:             adpcm->volume_w_step = (int)((double)adpcm->volume * (double)adpcm->step / (double)(1<<ADPCM_SHIFT));
                   2047:         }
                   2048:         break;
                   2049:     }
                   2050: }
                   2051: 
                   2052: #endif /* BUILD_FM_ADPCM */
                   2053: 
                   2054: 
                   2055: #if BUILD_YM2608
                   2056: /*******************************************************************************/
                   2057: /*      YM2608 local section                                                   */
                   2058: /*******************************************************************************/
                   2059: static YM2608 *FM2608=NULL; /* array of YM2608's */
                   2060: 
                   2061: #if 0
                   2062: /* Get next pcm data */
                   2063: INLINE int YM2608ReadADPCM(int n)
                   2064: {
                   2065:     YM2608 *F2608 = &(FM2608[n]);
                   2066:     if( F2608->ADMode & 0x20 )
                   2067:     {   /* buffer memory */
                   2068:         /* F2203->OPN.ST.status |= 0x04; */
                   2069:         return 0;
                   2070:     }
                   2071:     else
                   2072:     {   /* from PCM data register */
                   2073:         FM_STATUS_SET(F2608->OPN.ST,0x08); /* BRDY = 1 */
                   2074:         return F2608->ADData;
                   2075:     }
                   2076: }
                   2077: 
                   2078: /* Put decoded data */
                   2079: INLINE void YM2608WriteADPCM(int n,int v)
                   2080: {
                   2081:     YM2608 *F2608 = &(FM2608[n]);
                   2082:     if( F2608->ADMode & 0x20 )
                   2083:     {   /* for buffer */
                   2084:         return;
                   2085:     }
                   2086:     else
                   2087:     {   /* for PCM data port */
                   2088:         F2608->ADData = v;
                   2089:         FM_STATUS_SET(F2608->OPN.ST,0x08) /* BRDY = 1 */
                   2090:     }
                   2091: }
                   2092: #endif
                   2093: 
                   2094: /* ---------- IRQ flag Controll Write 0x110 ---------- */
                   2095: INLINE void YM2608IRQFlagWrite(FM_ST *ST,int n,int v)
                   2096: {
                   2097:     if( v & 0x80 )
                   2098:     {   /* Reset IRQ flag */
                   2099:         FM_STATUS_RESET(ST,0xff);
                   2100:     }
                   2101:     else
                   2102:     {   /* Set IRQ mask */
                   2103:         /* !!!!!!!!!! pending !!!!!!!!!! */
                   2104:         /* F2610->adpcm_statusmask = v & 0x1f; */
                   2105:     }
                   2106: }
                   2107: 
                   2108: #ifdef YM2608_RHYTHM_PCM
                   2109: /**** RYTHM (PCM) ****/
                   2110: INLINE void YM2608_RYTHM( YM2610 *F2610, ADPCM_CH *ch )
                   2111: 
                   2112: {
                   2113:     unsigned int step;
                   2114:     int data;
                   2115: 
                   2116:     ch->now_step += ch->step;
                   2117:     if ( ch->now_step >= (1<<ADPCM_SHIFT) )
                   2118:     {
                   2119:         step = ch->now_step >> ADPCM_SHIFT;
                   2120:         ch->now_step &= (1<<ADPCM_SHIFT)-1;
                   2121:         /* end check */
                   2122:         if ( (ch->now_addr+step) > (ch->end<<1) ) {
                   2123:             ch->flag = 0;
                   2124:             F2610->adpcm_arrivedEndAddress |= ch->flagMask & F2610->adpcm_statusmask;
                   2125:             return;
                   2126:         }
                   2127:         do{
                   2128:             /* get a next pcm data */
                   2129:             ch->adpcmx = ((short *)pcmbufA)[ch->now_addr];
                   2130:             ch->now_addr++;
                   2131:             /**** calc pcm * volume data ****/
                   2132:             ch->adpcml = ch->adpcmx * ch->volume;
                   2133:         }while(--step);
                   2134:     }
                   2135:     /* output for work of output channels (outd[OPNxxxx])*/
                   2136:     *(ch->pan) += ch->adpcml;
                   2137: }
                   2138: #endif /* YM2608_RHYTHM_PCM */
                   2139: 
                   2140: /* ---------- update one of chip ----------- */
                   2141: void YM2608UpdateOne(int num, void **buffer, int length)
                   2142: {
                   2143:     YM2608 *F2608 = &(FM2608[num]);
                   2144:     FM_OPN *OPN   = &(FM2608[num].OPN);
                   2145:     int dataR,dataL;
                   2146:     int i,j,ch;
                   2147: 
                   2148:     /* set bufer */
                   2149:     bufL = (FMSAMPLE *)buffer[0];
                   2150:     bufR = (FMSAMPLE *)buffer[1];
                   2151: 
                   2152:     if( (void *)F2608 != cur_chip ){
                   2153:         cur_chip = (void *)F2608;
                   2154: 
                   2155:         State = &OPN->ST;
                   2156:         cch[0]   = &F2608->CH[0];
                   2157:         cch[1]   = &F2608->CH[1];
                   2158:         cch[2]   = &F2608->CH[2];
                   2159:         cch[3]   = &F2608->CH[3];
                   2160:         cch[4]   = &F2608->CH[4];
                   2161:         cch[5]   = &F2608->CH[5];
                   2162:         /* setup adpcm rom address */
                   2163:         pcmbufB  = F2608->pcmbuf[0];
                   2164:         pcmsizeB = F2608->pcm_size[0];
                   2165:         pcmbufA  = F2608->pcmbuf[1];
                   2166:         pcmsizeA = F2608->pcm_size[1];
                   2167:     }
                   2168:     /* update frequency counter */
                   2169:     CALC_FCOUNT( cch[0] );
                   2170:     CALC_FCOUNT( cch[1] );
                   2171:     if( (State->mode & 0xc0) ){
                   2172:         /* 3SLOT MODE */
                   2173:         if( cch[2]->SLOT[SLOT1].Incr==-1){
                   2174:             /* 3 slot mode */
                   2175:             CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
                   2176:             CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
                   2177:             CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
                   2178:             CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
                   2179:         }
                   2180:     }else CALC_FCOUNT( cch[2] );
                   2181:     CALC_FCOUNT( cch[3] );
                   2182:     CALC_FCOUNT( cch[4] );
                   2183:     CALC_FCOUNT( cch[5] );
                   2184:     /* buffering */
                   2185:     for( i=0; i < length ; i++ )
                   2186:     {
                   2187:         /* clear output acc. */
                   2188:         outd[OPN_LEFT] = outd[OPN_RIGHT]= outd[OPN_CENTER] = 0;
                   2189:         /**** deltaT ADPCM ****/
                   2190:         if( F2608->adpcm[6].flag )
                   2191:             OPNB_ADPCM_CALC_CHB( F2608, &F2608->adpcm[6]);
                   2192:         /* FM */
                   2193:         FM_CALC_CH( cch[0] );
                   2194:         FM_CALC_CH( cch[1] );
                   2195:         FM_CALC_CH( cch[2] );
                   2196:         FM_CALC_CH( cch[3] );
                   2197:         FM_CALC_CH( cch[4] );
                   2198:         FM_CALC_CH( cch[5] );
                   2199:         for( j = 0; j < 6; j++ )
                   2200:         {
                   2201:             /**** ADPCM ****/
                   2202:             if( F2608->adpcm[j].flag )
                   2203: #ifdef YM2608_RHYTHM_PCM
                   2204:                 YM2608_RYTHM(F2608, &F2608->adpcm[j]);
                   2205: #else
                   2206:                 OPNB_ADPCM_CALC_CHA( F2608, &F2608->adpcm[j]);
                   2207: #endif
                   2208:         }
                   2209:         /* get left & right output with clipping */
                   2210:         dataL = Limit( outd[OPN_CENTER] + outd[OPN_LEFT], OPNB_MAXOUT, OPNB_MINOUT );
                   2211:         dataR = Limit( outd[OPN_CENTER] + outd[OPN_RIGHT], OPNB_MAXOUT, OPNB_MINOUT );
                   2212:         /* buffering */
                   2213:         /* stereo separate */
                   2214: #ifdef FM_STEREO_MIX        /* stereo mixing */
                   2215:         /* stereo mix */
                   2216:         ((FMSAMPLE_MIX *)bufL)[i] = ((dataL>>OPNB_OUTSB)<<FM_OUTPUT_BIT)|(dataR>>OPNB_OUTSB);
                   2217: #else
                   2218:         /* stereo separate */
                   2219:         bufL[i] = dataL>>OPNB_OUTSB;
                   2220:         bufR[i] = dataR>>OPNB_OUTSB;
                   2221: #endif
                   2222: 
                   2223: #ifdef LFO_SUPPORT
                   2224:         CALC_LOPM_LFO;
                   2225: #endif
                   2226: #ifdef INTERNAL_TIMER
                   2227:         /* timer controll */
                   2228:         CALC_TIMER_A( State , cch[2] );
                   2229: #endif
                   2230:     }
                   2231: #ifdef INTERNAL_TIMER
                   2232:     CALC_TIMER_B( State , length );
                   2233: #endif
                   2234: }
                   2235: 
                   2236: /* -------------------------- YM2608(OPNA) ---------------------------------- */
                   2237: int YM2608Init(int num, int clock, int rate,
                   2238:                void **pcmroma,int *pcmsizea,short *rhythmrom,int *rhythmpos,
                   2239:                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
                   2240: {
                   2241:     int i,j;
                   2242: 
                   2243:     if (FM2608) return (-1);    /* duplicate init. */
                   2244:     cur_chip = NULL;    /* hiro-shi!! */
                   2245: 
                   2246:     FMNumChips = num;
                   2247: 
                   2248:     /* allocate extend state space */
                   2249:     if( (FM2608 = (YM2608 *)malloc(sizeof(YM2608) * FMNumChips))==NULL)
                   2250:         return (-1);
                   2251:     /* clear */
                   2252:     memset(FM2608,0,sizeof(YM2608) * FMNumChips);
                   2253:     /* allocate total level table (128kb space) */
                   2254:     if( !FMInitTable() )
                   2255:     {
                   2256:         free( FM2608 );
                   2257:         return (-1);
                   2258:     }
                   2259: 
                   2260:     for ( i = 0 ; i < FMNumChips; i++ ) {
                   2261:         FM2608[i].OPN.ST.index = i;
                   2262:         FM2608[i].OPN.type = TYPE_YM2608;
                   2263:         FM2608[i].OPN.P_CH = FM2608[i].CH;
                   2264:         FM2608[i].OPN.ST.clock = clock;
                   2265:         FM2608[i].OPN.ST.rate = rate;
                   2266:         /* FM2608[i].OPN.ST.irq = 0; */
                   2267:         /* FM2608[i].OPN.ST.status = 0; */
                   2268:         FM2608[i].OPN.ST.timermodel = FM_TIMER_SINGLE;
                   2269:         /* Extend handler */
                   2270:         FM2608[i].OPN.ST.Timer_Handler = TimerHandler;
                   2271:         FM2608[i].OPN.ST.IRQ_Handler   = IRQHandler;
                   2272:         /* ADPCM */
                   2273:         FM2608[i].pcmbuf[0]   = (char *)(pcmroma[i]);
                   2274:         FM2608[i].pcm_size[0] = pcmsizea[i];
                   2275:         FM2608[i].pcmbuf[1]   = (char *)rhythmrom;
                   2276: #ifdef YM2608_RHYTHM_PCM
                   2277:         /* rhythm sound setup (PCM) */
                   2278:         for(j=0;j<6;j++)
                   2279:         {
                   2280:             /* rhythm sound */
                   2281:             FM2608[i].adpcm[j].start = rhythmpos[j];
                   2282:             FM2608[i].adpcm[j].end   = rhythmpos[j+1]-1;
                   2283:         }
                   2284:         FM2608[i].pcm_size[1] = rhythmpos[6];
                   2285: #else
                   2286:         /* rhythm sound setup (ADPCM) */
                   2287:         FM2608[i].pcm_size[1] = rhythmsize;
                   2288: #endif
                   2289:         YM2608ResetChip(i);
                   2290:     }
                   2291:     InitOPNB_ADPCMATable();
                   2292:     return 0;
                   2293: }
                   2294: 
                   2295: /* ---------- shut down emurator ----------- */
                   2296: void YM2608Shutdown()
                   2297: {
                   2298:     if (!FM2608) return;
                   2299: 
                   2300:     FMCloseTable();
                   2301:     free(FM2608);
                   2302:     FM2608 = NULL;
                   2303: }
                   2304: 
                   2305: /* ---------- reset one of chip ---------- */
                   2306: void YM2608ResetChip(int num)
                   2307: {
                   2308:     int i;
                   2309:     YM2608 *F2608 = &(FM2608[num]);
                   2310:     FM_OPN *OPN   = &(FM2608[num].OPN);
                   2311: 
                   2312:     /* Reset Priscaler */
                   2313:     OPNSetPris( OPN, 6*24, 6*24,4*2); /* OPN 1/6 , SSG 1/4 */
                   2314:     /* reset SSG section */
                   2315:     SSGReset(OPN->ST.index);
                   2316:     /* status clear */
                   2317:     FM_IRQMASK_SET(&OPN->ST,0x1f);
                   2318:     OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
                   2319: 
                   2320:     /* extend 3ch. disable */
                   2321:     /*OPN->type &= (~TYPE_6CH); */
                   2322: 
                   2323:     reset_channel( &OPN->ST , F2608->CH , 6 );
                   2324:     /* reset OPerator paramater */
                   2325:     for(i = 0xb6 ; i >= 0xb4 ; i-- )
                   2326:     {
                   2327:         OPNWriteReg(OPN,i      ,0xc0);
                   2328:         OPNWriteReg(OPN,i|0x100,0xc0);
                   2329:     }
                   2330:     for(i = 0xb2 ; i >= 0x30 ; i-- )
                   2331:     {
                   2332:         OPNWriteReg(OPN,i      ,0);
                   2333:         OPNWriteReg(OPN,i|0x100,0);
                   2334:     }
                   2335:     for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
                   2336:     /* reset ADPCM unit */
                   2337:     /**** ADPCM work initial ****/
                   2338:     for( i = 0; i < 6+1; i++ ){
                   2339:         F2608->adpcm[i].now_addr  = 0;
                   2340:         F2608->adpcm[i].now_step  = 0;
                   2341:         F2608->adpcm[i].step      = 0;
                   2342:         F2608->adpcm[i].start     = 0;
                   2343:         F2608->adpcm[i].end       = 0;
                   2344:         /* F2608->adpcm[i].delta     = 21866; */
                   2345:         F2608->adpcm[i].volume    = 0;
                   2346:         F2608->adpcm[i].pan       = &outd[OPN_CENTER]; /* default center */
                   2347:         F2608->adpcm[i].flagMask  = (i == 6) ? 0x20 : 0;
                   2348:         F2608->adpcm[i].flag      = 0;
                   2349:         F2608->adpcm[i].adpcmx    = 0;
                   2350:         F2608->adpcm[i].adpcmd    = 127;
                   2351:         F2608->adpcm[i].adpcml    = 0;
                   2352:         /* DELTA-T */
                   2353:         /*F2608->adpcm[i].adpcmm    = 0;*/
                   2354:         F2608->adpcm[i].volume_w_step = 0;
                   2355:         F2608->adpcm[i].next_leveling=0;
                   2356:     }
                   2357:     F2608->TL_adpcmb = &(TL_TABLE[0x3f*(int)(0.75/EG_STEP)]);
                   2358:     F2608->port0state = 0;
                   2359:     F2608->port0shift = 8;      /* allways 8bits shift */
                   2360:     /*F2608->port1state = 0; */
                   2361:     F2608->port1state = -1;
                   2362:     F2608->port1shift = 8;      /* allways 8bits shift */
                   2363:     F2608->adpcm_arrivedEndAddress = 0; /* don't used */
                   2364:     F2608->adpcm_statusmask = 0xbf;     /* don't used */
                   2365: }
                   2366: 
                   2367: /* YM2608 write */
                   2368: /* n = number  */
                   2369: /* a = address */
                   2370: /* v = value   */
                   2371: int YM2608Write(int n, int a,int v)
                   2372: {
                   2373:     YM2608 *F2608 = &(FM2608[n]);
                   2374:     FM_OPN *OPN   = &(FM2608[n].OPN);
                   2375:     int addr;
                   2376: 
                   2377:     switch(a&3){
                   2378:     case 0: /* address port 0 */
                   2379:         OPN->ST.address = v & 0xff;
                   2380:         /* Write register to SSG emurator */
                   2381:         if( v < 16 ) SSGWrite(n,0,v);
                   2382:         switch(OPN->ST.address)
                   2383:         {
                   2384:         case 0x2d:  /* divider sel */
                   2385:             OPNSetPris( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */
                   2386:             break;
                   2387:         case 0x2e:  /* divider sel */
                   2388:             OPNSetPris( OPN, 3*24, 3*24,2*2); /* OPN 1/3 , SSG 1/2 */
                   2389:             break;
                   2390:         case 0x2f:  /* divider sel */
                   2391:             OPNSetPris( OPN, 2*24, 2*24,1*2); /* OPN 1/2 , SSG 1/1 */
                   2392:             break;
                   2393:         }
                   2394:         break;
                   2395:     case 1: /* data port 0    */
                   2396:         addr = OPN->ST.address;
                   2397:         switch(addr & 0xf0)
                   2398:         {
                   2399:         case 0x00:  /* SSG section */
                   2400:             /* Write data to SSG emurator */
                   2401:             SSGWrite(n,a,v);
                   2402:             break;
                   2403:         case 0x10:  /* 0x10-0x1f : Rhythm section */
                   2404:             YM2608UpdateReq(n);
                   2405:             FM_ADPCMAWrite(F2608,addr-0x10,v);
                   2406:             break;
                   2407:         case 0x20:  /* Mode Register */
                   2408:             switch(addr)
                   2409:             {
                   2410:             case 0x29: /* SCH,xirq mask */
                   2411:                 /* SCH,xx,xxx,EN_ZERO,EN_BRDY,EN_EOS,EN_TB,EN_TA */
                   2412:                 /* extend 3ch. enable/disable */
                   2413:                 if(v&0x80) OPN->type |= TYPE_6CH;
                   2414:                 else       OPN->type &= ~TYPE_6CH;
                   2415:                 /* IRQ MASK */
                   2416:                 FM_IRQMASK_SET(&OPN->ST,v&0x1f);
                   2417:                 break;
                   2418:             default:
                   2419:                 YM2608UpdateReq(n);
                   2420:                 OPNWriteMode(OPN,addr,v);
                   2421:             }
                   2422:             break;
                   2423:         default:    /* OPN section */
                   2424:             YM2608UpdateReq(n);
                   2425:             OPNWriteReg(OPN,addr,v);
                   2426:         }
                   2427:         break;
                   2428:     case 2: /* address port 1 */
                   2429:         F2608->address1 = v & 0xff;
                   2430:         break;
                   2431:     case 3: /* data port 1    */
                   2432:         addr = F2608->address1;
                   2433:         YM2608UpdateReq(n);
                   2434:         switch( addr & 0xf0 )
                   2435:         {
                   2436:         case 0x00:  /* ADPCM PORT */
                   2437:             switch( addr )
                   2438:             {
                   2439:             case 0x0c:  /* Limit address L */
                   2440:                 /*F2608->ADLimit = (F2608->ADLimit & 0xff00) | v; */
                   2441:                 /*break; */
                   2442:             case 0x0d:  /* Limit address H */
                   2443:                 /*F2608->ADLimit = (F2608->ADLimit & 0x00ff) | (v<<8); */
                   2444:                 /*break; */
                   2445:             case 0x0e:  /* DAC data */
                   2446:                 /*break; */
                   2447:             case 0x0f:  /* PCM data port */
                   2448:                 /*F2608->ADData = v; */
                   2449:                 /*FM_STATUS_RESET(F2608->OPN.ST,0x08); */
                   2450:                 break;
                   2451:             default:
                   2452:                 /* 0x00-0x0b */
                   2453:                 FM_ADPCMBWrite(F2608,addr,v);
                   2454:             }
                   2455:             break;
                   2456:         case 0x10:  /* IRQ Flag controll */
                   2457:             if( addr == 0x10 )
                   2458:                 YM2608IRQFlagWrite(&(OPN->ST),n,v);
                   2459:             break;
                   2460:         default:
                   2461:             OPNWriteReg(OPN,addr|0x100,v);
                   2462:         }
                   2463:     }
                   2464:     return OPN->ST.irq;
                   2465: }
                   2466: unsigned char YM2608Read(int n,int a)
                   2467: {
                   2468:     YM2608 *F2608 = &(FM2608[n]);
                   2469:     int addr = F2608->OPN.ST.address;
                   2470:     int ret = 0;
                   2471: 
                   2472:     switch( a&3 ){
                   2473:     case 0: /* status 0 : YM2203 compatible */
                   2474:         /* BUSY:x:x:x:x:x:FLAGB:FLAGA */
                   2475:         if(addr==0xff) ret = 0x00; /* ID code */
                   2476:         else ret = F2608->OPN.ST.status & 0x83;
                   2477:         break;
                   2478:     case 1: /* status 0 */
                   2479:         if( addr < 16 ) ret = SSGRead(n);
                   2480:         break;
                   2481:     case 2: /* status 1 : + ADPCM status */
                   2482:         /* BUSY:x:PCMBUSY:ZERO:BRDY:EOS:FLAGB:FLAGA */
                   2483:         if(addr==0xff) ret = 0x00; /* ID code */
                   2484:         else ret = F2608->OPN.ST.status | (F2608->adpcm[6].flag ? 0x20 : 0);
                   2485:         break;
                   2486:     case 3:
                   2487:         ret = 0;
                   2488:         break;
                   2489:     }
                   2490:     return ret;
                   2491: }
                   2492: 
                   2493: int YM2608TimerOver(int n,int c)
                   2494: {
                   2495:     YM2608 *F2608 = &(FM2608[n]);
                   2496: 
                   2497:     if( c )
                   2498:     {   /* Timer B */
                   2499:         TimerBOver( &(F2608->OPN.ST) );
                   2500:     }
                   2501:     else
                   2502:     {   /* Timer A */
                   2503:         YM2608UpdateReq(n);
                   2504:         /* timer update */
                   2505:         TimerAOver( &(F2608->OPN.ST) );
                   2506:         /* CSM mode key,TL controll */
                   2507:         if( F2608->OPN.ST.mode & 0x80 )
                   2508:         {   /* CSM mode total level latch and auto key on */
                   2509:             CSMKeyControll( &(F2608->CH[2]) );
                   2510:         }
                   2511:     }
                   2512:     return FM2608->OPN.ST.irq;
                   2513: }
                   2514: 
                   2515: #if 0
                   2516: /* ---------- return the buffer ---------- */
                   2517: FMSAMPLE **YM2608Buffer(int n)
                   2518: {
                   2519:     return &(FM2608[n].Buf);
                   2520: }
                   2521: #endif
                   2522: 
                   2523: #if 0
                   2524: /* ---------- set buffer ---------- */
                   2525: int YM2608SetBuffer(int n, FMSAMPLE **buf )
                   2526: {
                   2527:     int i;
                   2528:     for( i = 0 ; i < YM2608_NUMBUF ; i++){
                   2529:         FM2608[n].Buf[i] = buf[i];
                   2530:         if( cur_chip == &FM2608[n] ) cur_chip = NULL;
                   2531:     }
                   2532:     return 0;
                   2533: }
                   2534: #endif
                   2535: 
                   2536: #endif /* BUILD_YM2608 */
                   2537: 
                   2538: #if BUILD_YM2610
                   2539: /* -------------------------- YM2610(OPNB) ---------------------------------- */
                   2540: /*static YM2610 *FM2610=NULL;      array of YM2610's    */
                   2541: 
                   2542: /* ---------- update one of chip (YM2610B FM6: ADPCM-A6: ADPCM-B:1) ----------- */
                   2543: void YM2610UpdateOne(int num, void **buffer, int length)
                   2544: {
                   2545:     YM2610 *F2610 = &(FM2610[num]);
                   2546:     FM_OPN *OPN   = &(FM2610[num].OPN);
                   2547:     static FMSAMPLE  *buf[YM2610_NUMBUF];
                   2548:     int dataR,dataL;
                   2549:     int i,j;
                   2550: 
                   2551:     /* buffer setup */
                   2552:     bufL = (FMSAMPLE *)buffer[0];
                   2553:     bufR = (FMSAMPLE *)buffer[1];
                   2554: 
                   2555:     if( (void *)F2610 != cur_chip ){
                   2556:         cur_chip = (void *)F2610;
                   2557:         State = &OPN->ST;
                   2558:         /*cch[0] = &F2610->CH[0]; */
                   2559:         cch[1] = &F2610->CH[1];
                   2560:         cch[2] = &F2610->CH[2];
                   2561:         /*cch[3] = &F2610->CH[3]; */
                   2562:         cch[4] = &F2610->CH[4];
                   2563:         cch[5] = &F2610->CH[5];
                   2564:         /* setup adpcm rom address */
                   2565:         pcmbufB  = F2610->pcmbuf[0];
                   2566:         pcmsizeB = F2610->pcm_size[0];
                   2567:         pcmbufA  = F2610->pcmbuf[1];
                   2568:         pcmsizeA = F2610->pcm_size[1];
                   2569:     }
                   2570: #ifdef YM2610B_WARNING
                   2571: #define FM_MSG_YM2610B "YM2610-%d.CH%d is playing,Check whether the type of the chip is YM2610B\n"
                   2572:     /* Check YM2610B worning message */
                   2573:     if(errorlog)
                   2574:     {
                   2575:         if( F2610->CH[0].SLOT[3].evm > ENV_MOD_OFF )
                   2576:             Log(LOG_WAR,FM_MSG_YM2610B,num,0);
                   2577:         if( F2610->CH[3].SLOT[3].evm > ENV_MOD_OFF )
                   2578:             Log(LOG_WAR,FM_MSG_YM2610B,num,3);
                   2579:     }
                   2580: #endif
                   2581:     /* update frequency counter */
                   2582:     /*CALC_FCOUNT( cch[0] ); */
                   2583:     CALC_FCOUNT( cch[1] );
                   2584:     if( (State->mode & 0xc0) ){
                   2585:         /* 3SLOT MODE */
                   2586:         if( cch[2]->SLOT[SLOT1].Incr==-1){
                   2587:             /* 3 slot mode */
                   2588:             CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
                   2589:             CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
                   2590:             CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
                   2591:             CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
                   2592:         }
                   2593:     }else CALC_FCOUNT( cch[2] );
                   2594:     /*CALC_FCOUNT( cch[3] ); */
                   2595:     CALC_FCOUNT( cch[4] );
                   2596:     CALC_FCOUNT( cch[5] );
                   2597: 
                   2598:     /* buffering */
                   2599:     for( i=0; i < length ; i++ )
                   2600:     {
                   2601:         /* clear output acc. */
                   2602:         outd[OPN_LEFT] = outd[OPN_RIGHT]= outd[OPN_CENTER] = 0;
                   2603:         /**** deltaT ADPCM ****/
                   2604:         if( F2610->adpcm[6].flag )
                   2605:             OPNB_ADPCM_CALC_CHB( F2610, &F2610->adpcm[6]);
                   2606:         /* FM */
                   2607:         /*FM_CALC_CH( cch[0] ); */
                   2608:         FM_CALC_CH( cch[1] );
                   2609:         FM_CALC_CH( cch[2] );
                   2610:         /*FM_CALC_CH( cch[3] ); */
                   2611:         FM_CALC_CH( cch[4] );
                   2612:         FM_CALC_CH( cch[5] );
                   2613:         for( j = 0; j < 6; j++ )
                   2614:         {
                   2615:             /**** ADPCM ****/
                   2616:             if( F2610->adpcm[j].flag )
                   2617:                 OPNB_ADPCM_CALC_CHA( F2610, &F2610->adpcm[j]);
                   2618:         }
                   2619:         /* get left & right output with clipping */
                   2620:         dataL = Limit( outd[OPN_CENTER] + outd[OPN_LEFT], OPNB_MAXOUT, OPNB_MINOUT );
                   2621:         dataR = Limit( outd[OPN_CENTER] + outd[OPN_RIGHT], OPNB_MAXOUT, OPNB_MINOUT );
                   2622:         /* buffering */
                   2623: #ifdef FM_STEREO_MIX        /* stereo mixing */
                   2624:         /* stereo mix */
                   2625:         ((FMSAMPLE_MIX *)bufL)[i] = ((dataL>>OPNB_OUTSB)<<FM_OUTPUT_BIT)|(dataR>>OPNB_OUTSB);
                   2626: #else
                   2627:         /* stereo separate */
                   2628:         bufL[i] = dataL>>OPNB_OUTSB;
                   2629:         bufR[i] = dataR>>OPNB_OUTSB;
                   2630: #endif
                   2631: 
                   2632: #ifdef LFO_SUPPORT
                   2633:         CALC_LOPM_LFO;
                   2634: #endif
                   2635: #ifdef INTERNAL_TIMER
                   2636:         /* timer controll */
                   2637:         CALC_TIMER_A( State , cch[2] );
                   2638: #endif
                   2639:     }
                   2640: #ifdef INTERNAL_TIMER
                   2641:     CALC_TIMER_B( State , length );
                   2642: #endif
                   2643: }
                   2644: #endif /* BUILD_YM2610 */
                   2645: 
                   2646: #if BUILD_YM2610B
                   2647: /* ---------- update one of chip (YM2610B FM6: ADPCM-A6: ADPCM-B:1) ----------- */
                   2648: void YM2610BUpdateOne(int num, void **buffer, int length)
                   2649: {
                   2650:     YM2610 *F2610 = &(FM2610[num]);
                   2651:     FM_OPN *OPN   = &(FM2610[num].OPN);
                   2652:     static FMSAMPLE  *buf[YM2610_NUMBUF];
                   2653:     int dataR,dataL;
                   2654:     int i,j;
                   2655: 
                   2656:     /* buffer setup */
                   2657:     bufL = (FMSAMPLE *)buffer[0];
                   2658:     bufR = (FMSAMPLE *)buffer[1];
                   2659: 
                   2660:     if( (void *)F2610 != cur_chip ){
                   2661:         cur_chip = (void *)F2610;
                   2662:         State = &OPN->ST;
                   2663:         cch[0] = &F2610->CH[0];
                   2664:         cch[1] = &F2610->CH[1];
                   2665:         cch[2] = &F2610->CH[2];
                   2666:         cch[3] = &F2610->CH[3];
                   2667:         cch[4] = &F2610->CH[4];
                   2668:         cch[5] = &F2610->CH[5];
                   2669:         /* setup adpcm rom address */
                   2670:         pcmbufB  = F2610->pcmbuf[0];
                   2671:         pcmsizeB = F2610->pcm_size[0];
                   2672:         pcmbufA  = F2610->pcmbuf[1];
                   2673:         pcmsizeA = F2610->pcm_size[1];
                   2674:     }
                   2675: 
                   2676:     /* update frequency counter */
                   2677:     CALC_FCOUNT( cch[0] );
                   2678:     CALC_FCOUNT( cch[1] );
                   2679:     if( (State->mode & 0xc0) ){
                   2680:         /* 3SLOT MODE */
                   2681:         if( cch[2]->SLOT[SLOT1].Incr==-1){
                   2682:             /* 3 slot mode */
                   2683:             CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
                   2684:             CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
                   2685:             CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
                   2686:             CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
                   2687:         }
                   2688:     }else CALC_FCOUNT( cch[2] );
                   2689:     CALC_FCOUNT( cch[3] );
                   2690:     CALC_FCOUNT( cch[4] );
                   2691:     CALC_FCOUNT( cch[5] );
                   2692: 
                   2693:     /* buffering */
                   2694:     for( i=0; i < length ; i++ )
                   2695:     {
                   2696:         /* clear output acc. */
                   2697:         outd[OPN_LEFT] = outd[OPN_RIGHT]= outd[OPN_CENTER] = 0;
                   2698:         /**** deltaT ADPCM ****/
                   2699:         if( F2610->adpcm[6].flag )
                   2700:             OPNB_ADPCM_CALC_CHB( F2610, &F2610->adpcm[6]);
                   2701:         /* FM */
                   2702:         FM_CALC_CH( cch[0] );
                   2703:         FM_CALC_CH( cch[1] );
                   2704:         FM_CALC_CH( cch[2] );
                   2705:         FM_CALC_CH( cch[3] );
                   2706:         FM_CALC_CH( cch[4] );
                   2707:         FM_CALC_CH( cch[5] );
                   2708:         for( j = 0; j < 6; j++ )
                   2709:         {
                   2710:             /**** ADPCM ****/
                   2711:             if( F2610->adpcm[j].flag )
                   2712:                 OPNB_ADPCM_CALC_CHA( F2610, &F2610->adpcm[j]);
                   2713:         }
                   2714:         /* get left & right output with clipping */
                   2715:         dataL = Limit( outd[OPN_CENTER] + outd[OPN_LEFT], OPNB_MAXOUT, OPNB_MINOUT );
                   2716:         dataR = Limit( outd[OPN_CENTER] + outd[OPN_RIGHT], OPNB_MAXOUT, OPNB_MINOUT );
                   2717:         /* buffering */
                   2718:         /* stereo separate */
                   2719: #ifdef FM_STEREO_MIX        /* stereo mixing */
                   2720:         /* stereo mix */
                   2721:         ((FMSAMPLE_MIX *)bufL)[i] = ((dataL>>OPNB_OUTSB)<<FM_OUTPUT_BIT)|(dataR>>OPNB_OUTSB);
                   2722: #else
                   2723:         /* stereo separate */
                   2724:         bufL[i] = dataL>>OPNB_OUTSB;
                   2725:         bufR[i] = dataR>>OPNB_OUTSB;
                   2726: #endif
                   2727: 
                   2728: #ifdef LFO_SUPPORT
                   2729:         CALC_LOPM_LFO;
                   2730: #endif
                   2731: #ifdef INTERNAL_TIMER
                   2732:         /* timer controll */
                   2733:         CALC_TIMER_A( State , cch[2] );
                   2734: #endif
                   2735:     }
                   2736: #ifdef INTERNAL_TIMER
                   2737:     CALC_TIMER_B( State , length );
                   2738: #endif
                   2739: }
                   2740: #endif /* BUILD_YM2610B */
                   2741: 
                   2742: #if BUILD_OPNB
                   2743: int YM2610Init(int num, int clock, int rate,
                   2744:                void **pcmroma,int *pcmsizea,void **pcmromb,int *pcmsizeb,
                   2745:                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
                   2746: 
                   2747: {
                   2748:     int i,j;
                   2749: 
                   2750:     if (FM2610) return (-1);    /* duplicate init. */
                   2751:     cur_chip = NULL;    /* hiro-shi!! */
                   2752: 
                   2753:     FMNumChips = num;
                   2754: 
                   2755:     /* allocate extend state space */
                   2756:     if( (FM2610 = (YM2610 *)malloc(sizeof(YM2610) * FMNumChips))==NULL)
                   2757:         return (-1);
                   2758:     /* clear */
                   2759:     memset(FM2610,0,sizeof(YM2610) * FMNumChips);
                   2760:     /* allocate total level table (128kb space) */
                   2761:     if( !FMInitTable() )
                   2762:     {
                   2763:         free( FM2610 );
                   2764:         return (-1);
                   2765:     }
                   2766: 
                   2767:     for ( i = 0 ; i < FMNumChips; i++ ) {
                   2768:         /* FM */
                   2769:         FM2610[i].OPN.ST.index = i;
                   2770:         FM2610[i].OPN.type = TYPE_YM2610;
                   2771:         FM2610[i].OPN.P_CH = FM2610[i].CH;
                   2772:         FM2610[i].OPN.ST.clock = clock;
                   2773:         FM2610[i].OPN.ST.rate = rate;
                   2774:         /* FM2610[i].OPN.ST.irq = 0; */
                   2775:         /* FM2610[i].OPN.ST.status = 0; */
                   2776:         FM2610[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
                   2777:         /* Extend handler */
                   2778:         FM2610[i].OPN.ST.Timer_Handler = TimerHandler;
                   2779:         FM2610[i].OPN.ST.IRQ_Handler   = IRQHandler;
                   2780:         /* ADPCM */
                   2781:         FM2610[i].pcmbuf[0]   = (char *)(pcmroma[i]);
                   2782:         FM2610[i].pcm_size[0] = pcmsizea[i];
                   2783:         FM2610[i].pcmbuf[1]   = (char *)(pcmromb[i]);
                   2784:         FM2610[i].pcm_size[1] = pcmsizeb[i];
                   2785:         /* */
                   2786:         YM2610ResetChip(i);
                   2787:     }
                   2788:     InitOPNB_ADPCMATable();
                   2789:     return 0;
                   2790: }
                   2791: 
                   2792: /* ---------- shut down emurator ----------- */
                   2793: void YM2610Shutdown()
                   2794: {
                   2795:     if (!FM2610) return;
                   2796: 
                   2797:     FMCloseTable();
                   2798:     free(FM2610);
                   2799:     FM2610 = NULL;
                   2800: }
                   2801: 
                   2802: #if 0
                   2803: unsigned int getNowAdpcmAddr( int num ){
                   2804:   return FM2610[0].adpcm[num].now_addr;
                   2805: }
                   2806: unsigned char getNowAdpcmReg( int port, int num ){
                   2807:   return FM2610[0].adpcmreg[port][num];
                   2808: }
                   2809: #endif
                   2810: 
                   2811: /* ---------- reset one of chip ---------- */
                   2812: void YM2610ResetChip(int num)
                   2813: {
                   2814:     int i;
                   2815:     YM2610 *F2610 = &(FM2610[num]);
                   2816:     FM_OPN *OPN   = &(FM2610[num].OPN);
                   2817: 
                   2818:     /* Reset Priscaler */
                   2819:     OPNSetPris( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */
                   2820:     /* reset SSG section */
                   2821:     SSGReset(OPN->ST.index);
                   2822:     /* status clear */
                   2823:     FM_IRQMASK_SET(&OPN->ST,0x03);
                   2824:     OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
                   2825: 
                   2826:     reset_channel( &OPN->ST , F2610->CH , 6 );
                   2827:     /* reset OPerator paramater */
                   2828:     for(i = 0xb6 ; i >= 0xb4 ; i-- )
                   2829:     {
                   2830:         OPNWriteReg(OPN,i      ,0xc0);
                   2831:         OPNWriteReg(OPN,i|0x100,0xc0);
                   2832:     }
                   2833:     for(i = 0xb2 ; i >= 0x30 ; i-- )
                   2834:     {
                   2835:         OPNWriteReg(OPN,i      ,0);
                   2836:         OPNWriteReg(OPN,i|0x100,0);
                   2837:     }
                   2838:     for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
                   2839:     /**** ADPCM work initial ****/
                   2840:     for( i = 0; i < 6+1; i++ ){
                   2841:         F2610->adpcm[i].now_addr  = 0;
                   2842:         F2610->adpcm[i].now_step  = 0;
                   2843:         F2610->adpcm[i].step      = 0;
                   2844:         F2610->adpcm[i].start     = 0;
                   2845:         F2610->adpcm[i].end       = 0;
                   2846:         /* F2610->adpcm[i].delta     = 21866; */
                   2847:         F2610->adpcm[i].volume    = 0;
                   2848:         F2610->adpcm[i].pan       = &outd[OPN_CENTER]; /* default center */
                   2849:         F2610->adpcm[i].flagMask  = (i == 6) ? 0x80 : (1<<i);
                   2850:         F2610->adpcm[i].flag      = 0;
                   2851:         F2610->adpcm[i].adpcmx    = 0;
                   2852:         F2610->adpcm[i].adpcmd    = 127;
                   2853:         F2610->adpcm[i].adpcml    = 0;
                   2854:         /* DELTA-T */
                   2855:         /*F2610->adpcm[i].adpcmm    = 0;*/
                   2856:         F2610->adpcm[i].volume_w_step = 0;
                   2857:         F2610->adpcm[i].next_leveling=0;
                   2858:     }
                   2859:     F2610->TL_adpcmb = &(TL_TABLE[0x3f*(int)(0.75/EG_STEP)]);
                   2860:     F2610->port0state = 0;
                   2861:     F2610->port0shift = 8;      /* allways 8bits shift */
                   2862:     /*F2610->port1state = 0; */
                   2863:     F2610->port1state = -1;
                   2864:     F2610->port1shift = 8;      /* allways 8bits shift */
                   2865:     F2610->adpcm_arrivedEndAddress = 0;
                   2866:     F2610->adpcm_statusmask = 0xbf;
                   2867: }
                   2868: 
                   2869: /* YM2610 write */
                   2870: /* n = number  */
                   2871: /* a = address */
                   2872: /* v = value   */
                   2873: int YM2610Write(int n, int a,int v)
                   2874: {
                   2875:     YM2610 *F2610 = &(FM2610[n]);
                   2876:     FM_OPN *OPN   = &(FM2610[n].OPN);
                   2877:     int addr;
                   2878: 
                   2879:     switch( a&3 ){
                   2880:     case 0: /* address port 0 */
                   2881:         OPN->ST.address = v & 0xff;
                   2882:         /* Write register to SSG emurator */
                   2883:         if( v < 16 ) SSGWrite(n,0,v);
                   2884:         break;
                   2885:     case 1: /* data port 0    */
                   2886:         addr = OPN->ST.address;
                   2887:         switch(addr & 0xf0)
                   2888:         {
                   2889:         case 0x00:  /* SSG section */
                   2890:             /* Write data to SSG emurator */
                   2891:             SSGWrite(n,a,v);
                   2892:             break;
                   2893:         case 0x10: /* DeltaT ADPCM */
                   2894:             YM2610UpdateReq(n);
                   2895:             switch(addr)
                   2896:             {
                   2897:             case 0x1c: /*  FLAG CONTROL : Extend Status Clear/Mask */
                   2898:                 F2610->adpcm_statusmask = ~v;
                   2899:                 F2610->adpcm_arrivedEndAddress &= F2610->adpcm_statusmask;
                   2900:                 break;
                   2901:             default:
                   2902:                 /* 0x10-0x1b */
                   2903:                 FM_ADPCMBWrite(F2610,addr & 0x0f,v);
                   2904:             }
                   2905:             break;
                   2906:         case 0x20:  /* Mode Register */
                   2907:             YM2610UpdateReq(n);
                   2908:             OPNWriteMode(OPN,addr,v);
                   2909:             break;
                   2910:         default:    /* OPN section */
                   2911:             YM2610UpdateReq(n);
                   2912:             /* write register */
                   2913:              OPNWriteReg(OPN,addr,v);
                   2914:         }
                   2915:         break;
                   2916:     case 2: /* address port 1 */
                   2917:         F2610->address1 = v & 0xff;
                   2918:         break;
                   2919:     case 3: /* data port 1    */
                   2920:         YM2610UpdateReq(n);
                   2921:         addr = F2610->address1;
                   2922:         if( addr < 0x30 )
                   2923:             /* 100-12f : ADPCM A section */
                   2924:             FM_ADPCMAWrite(F2610,addr,v);
                   2925:         else
                   2926:             OPNWriteReg(OPN,addr|0x100,v);
                   2927:     }
                   2928:     return OPN->ST.irq;
                   2929: }
                   2930: unsigned char YM2610Read(int n,int a)
                   2931: {
                   2932:     YM2610 *F2610 = &(FM2610[n]);
                   2933:     int addr = F2610->OPN.ST.address;
                   2934:     unsigned char ret = 0;
                   2935:     int i = 0;
                   2936: 
                   2937:     switch( a&3){
                   2938:     case 0: /* status 0 : YM2203 compatible */
                   2939:         ret = F2610->OPN.ST.status & 0x83;
                   2940:         break;
                   2941:     case 1: /* data 0 */
                   2942:         if( addr < 16 ) ret = SSGRead(n);
                   2943:         if( addr == 0xff ) ret = 0x01;
                   2944:         break;
                   2945:     case 2: /* status 1 : + ADPCM status */
                   2946:         /* ADPCM STATUS (arrived End Address) */
                   2947:         /* B,--,A5,A4,A3,A2,A1,A0 */
                   2948:         /* B     = ADPCM-B(DELTA-T) arrived end address */
                   2949:         /* A0-A5 = ADPCM-A          arrived end address */
                   2950: #if 0
                   2951:         ret = 0;
                   2952:         for( i=0;i<7;i++)
                   2953:             if(!(F2610->adpcm[i].flag)) ret |= F2610->adpcm[i].flagMask;
                   2954:         ret &= F2610->adpcm_statusmask;
                   2955: #else
                   2956:         ret = F2610->adpcm_arrivedEndAddress;
                   2957: #endif
                   2958: #ifdef __RAINE__
                   2959:       /*PrintDebug( "YM2610Status2 %02x\n", ret ); */
                   2960:       /*PrintIngame(120,"YM2610Status2 %02x", ret ); */
                   2961: #endif
                   2962:         break;
                   2963:     case 3:
                   2964:         ret = 0;
                   2965:         break;
                   2966:     }
                   2967:     return ret;
                   2968: }
                   2969: 
                   2970: int YM2610TimerOver(int n,int c)
                   2971: {
                   2972:     YM2610 *F2610 = &(FM2610[n]);
                   2973: 
                   2974:     if( c )
                   2975:     {   /* Timer B */
                   2976:         TimerBOver( &(F2610->OPN.ST) );
                   2977:     }
                   2978:     else
                   2979:     {   /* Timer A */
                   2980:         YM2610UpdateReq(n);
                   2981:         /* timer update */
                   2982:         TimerAOver( &(F2610->OPN.ST) );
                   2983:         /* CSM mode key,TL controll */
                   2984:         if( F2610->OPN.ST.mode & 0x80 )
                   2985:         {   /* CSM mode total level latch and auto key on */
                   2986:             CSMKeyControll( &(F2610->CH[2]) );
                   2987:         }
                   2988:     }
                   2989:     return F2610->OPN.ST.irq;
                   2990: }
                   2991: 
                   2992: #if 0
                   2993: /* ---------- return the buffer ---------- */
                   2994: FMSAMPLE *YM2610Buffer(int n)
                   2995: {
                   2996:     return FMOPN[n].Buf[0];
                   2997: }
                   2998: #endif
                   2999: 
                   3000: #if 0
                   3001: /* ---------- set buffer ---------- */
                   3002: int YM2610SetBuffer(int n, FMSAMPLE **buf )
                   3003: {
                   3004:     int i;
                   3005:     for( i = 0 ; i < YM2610_NUMBUF ; i++){
                   3006:         FM2610[n].Buf[i] = buf[i];
                   3007:         /*if( cur_chip == &FM2610[n] ) cur_chip = NULL;*/
                   3008:     }
                   3009:     return 0;
                   3010: }
                   3011: #endif
                   3012: 
                   3013: #endif /* BUILD_YM2610 */
                   3014: 
                   3015: 
                   3016: #if BUILD_YM2612
                   3017: /*******************************************************************************/
                   3018: /*      YM2612 local section                                                   */
                   3019: /*******************************************************************************/
                   3020: static YM2612 *FM2612=NULL; /* array of YM2612's */
                   3021: 
                   3022: /* ---------- update one of chip ----------- */
                   3023: void YM2612UpdateOne(int num, void **buffer, int length)
                   3024: {
                   3025:     YM2612 *F2612 = &(FM2612[num]);
                   3026:     FM_OPN *OPN   = &(FM2612[num].OPN);
                   3027:     int dataR,dataL;
                   3028:     int i,ch;
                   3029:     int dacen = F2612->dacen;
                   3030:     int dacout  = F2612->dacout;
                   3031: 
                   3032:     /* set bufer */
                   3033:     bufL = (FMSAMPLE *)buffer[0];
                   3034:     bufR = (FMSAMPLE *)buffer[1];
                   3035: 
                   3036:     if( (void *)F2612 != cur_chip ){
                   3037:         cur_chip = (void *)F2612;
                   3038: 
                   3039:         State = &OPN->ST;
                   3040:         cch[0]   = &F2612->CH[0];
                   3041:         cch[1]   = &F2612->CH[1];
                   3042:         cch[2]   = &F2612->CH[2];
                   3043:         cch[3]   = &F2612->CH[3];
                   3044:         cch[4]   = &F2612->CH[4];
                   3045:         cch[5]   = &F2612->CH[5];
                   3046:     }
                   3047:     /* update frequency counter */
                   3048:     CALC_FCOUNT( cch[0] );
                   3049:     CALC_FCOUNT( cch[1] );
                   3050:     if( (State->mode & 0xc0) ){
                   3051:         /* 3SLOT MODE */
                   3052:         if( cch[2]->SLOT[SLOT1].Incr==-1){
                   3053:             /* 3 slot mode */
                   3054:             CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
                   3055:             CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
                   3056:             CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
                   3057:             CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
                   3058:         }
                   3059:     }else CALC_FCOUNT( cch[2] );
                   3060:     CALC_FCOUNT( cch[3] );
                   3061:     CALC_FCOUNT( cch[4] );
                   3062:     CALC_FCOUNT( cch[5] );
                   3063:     /* buffering */
                   3064:     for( i=0; i < length ; i++ )
                   3065:     {
                   3066:         /* clear output acc. */
                   3067:         outd[OPN_LEFT] = outd[OPN_RIGHT]= outd[OPN_CENTER] = 0;
                   3068:         /* calcrate channel output */
                   3069:         for( ch=0;ch<5;ch++) FM_CALC_CH( cch[ch] );
                   3070:         if( dacen )  *cch[5]->connect4 += dacout;
                   3071:         else         FM_CALC_CH( cch[5] );
                   3072:         /* get left & right output */
                   3073:         dataL = Limit( outd[OPN_CENTER] + outd[OPN_LEFT], OPN_MAXOUT, OPN_MINOUT );
                   3074:         dataR = Limit( outd[OPN_CENTER] + outd[OPN_RIGHT], OPN_MAXOUT, OPN_MINOUT );
                   3075:         /* buffering */
                   3076: #ifdef FM_STEREO_MIX        /* stereo mixing */
                   3077:         /* stereo mix */
                   3078:         ((FMSAMPLE_MIX *)bufL)[i] = ((dataL>>OPN_OUTSB)<<FM_OUTPUT_BIT)|(dataR>>OPN_OUTSB);
                   3079: #else
                   3080:         /* stereo separate */
                   3081:         bufL[i] = dataL>>OPN_OUTSB;
                   3082:         bufR[i] = dataR>>OPN_OUTSB;
                   3083: #endif
                   3084: 
                   3085: #ifdef LFO_SUPPORT
                   3086:         CALC_LOPM_LFO;
                   3087: #endif
                   3088: #ifdef INTERNAL_TIMER
                   3089:         /* timer controll */
                   3090:         CALC_TIMER_A( State , cch[2] );
                   3091: #endif
                   3092:     }
                   3093: #ifdef INTERNAL_TIMER
                   3094:     CALC_TIMER_B( State , length );
                   3095: #endif
                   3096: }
                   3097: 
                   3098: /* -------------------------- YM2612 ---------------------------------- */
                   3099: int YM2612Init(int num, int clock, int rate,
                   3100:                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
                   3101: {
                   3102:     int i,j;
                   3103: 
                   3104:     if (FM2612) return (-1);    /* duplicate init. */
                   3105:     cur_chip = NULL;    /* hiro-shi!! */
                   3106: 
                   3107:     FMNumChips = num;
                   3108: 
                   3109:     /* allocate extend state space */
                   3110:     if( (FM2612 = (YM2612 *)malloc(sizeof(YM2612) * FMNumChips))==NULL)
                   3111:         return (-1);
                   3112:     /* clear */
                   3113:     memset(FM2612,0,sizeof(YM2612) * FMNumChips);
                   3114:     /* allocate total level table (128kb space) */
                   3115:     if( !FMInitTable() )
                   3116:     {
                   3117:         free( FM2612 );
                   3118:         return (-1);
                   3119:     }
                   3120: 
                   3121:     for ( i = 0 ; i < FMNumChips; i++ ) {
                   3122:         FM2612[i].OPN.ST.index = i;
                   3123:         FM2612[i].OPN.type = TYPE_YM2612;
                   3124:         FM2612[i].OPN.P_CH = FM2612[i].CH;
                   3125:         FM2612[i].OPN.ST.clock = clock;
                   3126:         FM2612[i].OPN.ST.rate = rate;
                   3127:         /* FM2612[i].OPN.ST.irq = 0; */
                   3128:         /* FM2612[i].OPN.ST.status = 0; */
                   3129:         FM2612[i].OPN.ST.timermodel = FM_TIMER_SINGLE;
                   3130:         /* Extend handler */
                   3131:         FM2612[i].OPN.ST.Timer_Handler = TimerHandler;
                   3132:         FM2612[i].OPN.ST.IRQ_Handler   = IRQHandler;
                   3133:         YM2612ResetChip(i);
                   3134:     }
                   3135:     return 0;
                   3136: }
                   3137: 
                   3138: /* ---------- shut down emurator ----------- */
                   3139: void YM2612Shutdown()
                   3140: {
                   3141:     if (!FM2612) return;
                   3142: 
                   3143:     FMCloseTable();
                   3144:     free(FM2612);
                   3145:     FM2612 = NULL;
                   3146: }
                   3147: 
                   3148: /* ---------- reset one of chip ---------- */
                   3149: void YM2612ResetChip(int num)
                   3150: {
                   3151:     int i;
                   3152:     YM2612 *F2612 = &(FM2612[num]);
                   3153:     FM_OPN *OPN   = &(FM2612[num].OPN);
                   3154: 
                   3155:     OPNSetPris( OPN , 12*12, 12*12, 0);
                   3156:     /* status clear */
                   3157:     FM_IRQMASK_SET(&OPN->ST,0x03);
                   3158:     OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
                   3159: 
                   3160:     reset_channel( &OPN->ST , &F2612->CH[0] , 6 );
                   3161: 
                   3162:     for(i = 0xb6 ; i >= 0xb4 ; i-- )
                   3163:     {
                   3164:         OPNWriteReg(OPN,i      ,0xc0);
                   3165:         OPNWriteReg(OPN,i|0x100,0xc0);
                   3166:     }
                   3167:     for(i = 0xb2 ; i >= 0x30 ; i-- )
                   3168:     {
                   3169:         OPNWriteReg(OPN,i      ,0);
                   3170:         OPNWriteReg(OPN,i|0x100,0);
                   3171:     }
                   3172:     for(i = 0x26 ; i >= 0x20 ; i-- ) {OPNWriteReg(OPN,i,0);OPNWriteReg(OPN,i|0x100,0);}
                   3173:     /* DAC mode clear */
                   3174:     F2612->dacen = 0;
                   3175: }
                   3176: 
                   3177: /* YM2612 write */
                   3178: /* n = number  */
                   3179: /* a = address */
                   3180: /* v = value   */
                   3181: int YM2612Write(int n, int a,int v)
                   3182: {
                   3183:     YM2612 *F2612 = &(FM2612[n]);
                   3184:     int addr;
                   3185: 
                   3186:     switch( a&3){
                   3187:     case 0: /* address port 0 */
                   3188:         F2612->OPN.ST.address = v & 0xff;
                   3189:         break;
                   3190:     case 1: /* data port 0    */
                   3191:         addr = F2612->OPN.ST.address;
                   3192:         switch( addr & 0xf0 )
                   3193:         {
                   3194:         case 0x20:  /* 0x20-0x2f Mode */
                   3195:             switch( addr )
                   3196:             {
                   3197:             case 0x2a:  /* DAC data (YM2612) */
                   3198:                 YM2612UpdateReq(n);
                   3199:                 F2612->dacout = v<<(TL_BITS-8);
                   3200:                break; /* jp 3/6/99 */
                   3201:             case 0x2b:  /* DAC Sel  (YM2612) */
                   3202:                 /* b7 = dac enable */
                   3203:                F2612->dacen = v & 0x80;
                   3204:                 break;
                   3205:             default:    /* OPN section */
                   3206:                 YM2612UpdateReq(n);
                   3207:                 /* write register */
                   3208:                  OPNWriteMode(&(F2612->OPN),addr,v);
                   3209:             }
                   3210:             break;
                   3211:         default:    /* 0x30-0xff OPN section */
                   3212:             YM2612UpdateReq(n);
                   3213:             /* write register */
                   3214:              OPNWriteReg(&(F2612->OPN),addr,v);
                   3215:         }
                   3216:         break;
                   3217:     case 2: /* address port 1 */
                   3218:         F2612->address1 = v & 0xff;
                   3219:         break;
                   3220:     case 3: /* data port 1    */
                   3221:         addr = F2612->address1;
                   3222:         YM2612UpdateReq(n);
                   3223:         OPNWriteReg(&(F2612->OPN),addr|0x100,v);
                   3224:         break;
                   3225:     }
                   3226:     return F2612->OPN.ST.irq;
                   3227: }
                   3228: unsigned char YM2612Read(int n,int a)
                   3229: {
                   3230:     YM2612 *F2612 = &(FM2612[n]);
                   3231:     int addr = F2612->OPN.ST.address;
                   3232: 
                   3233:     switch( a&3){
                   3234:     case 0: /* status 0 */
                   3235:         return F2612->OPN.ST.status;
                   3236:     case 1:
                   3237:     case 2:
                   3238:     case 3:
                   3239:         Log(LOG_WAR,"YM2612 #%d:A=%d read unmapped area\n");
                   3240:         return F2612->OPN.ST.status;
                   3241:     }
                   3242:     return 0;
                   3243: }
                   3244: 
                   3245: int YM2612TimerOver(int n,int c)
                   3246: {
                   3247:     YM2612 *F2612 = &(FM2612[n]);
                   3248: 
                   3249:     if( c )
                   3250:     {   /* Timer B */
                   3251:         TimerBOver( &(F2612->OPN.ST) );
                   3252:     }
                   3253:     else
                   3254:     {   /* Timer A */
                   3255:         YM2612UpdateReq(n);
                   3256:         /* timer update */
                   3257:         TimerAOver( &(F2612->OPN.ST) );
                   3258:         /* CSM mode key,TL controll */
                   3259:         if( F2612->OPN.ST.mode & 0x80 )
                   3260:         {   /* CSM mode total level latch and auto key on */
                   3261:             CSMKeyControll( &(F2612->CH[2]) );
                   3262:         }
                   3263:     }
                   3264:     return F2612->OPN.ST.irq;
                   3265: }
                   3266: 
                   3267: #if 0
                   3268: /* ---------- set buffer ---------- */
                   3269: int YM2612SetBuffer(int n, FMSAMPLE **buf )
                   3270: {
                   3271:     int i;
                   3272:     for( i = 0 ; i < YM2612_NUMBUF ; i++){
                   3273:         FM2612[n].Buf[i] = buf[i];
                   3274:         if( cur_chip == &FM2612[n] ) cur_chip = NULL;
                   3275:     }
                   3276:     return 0;
                   3277: }
                   3278: #endif
                   3279: 
                   3280: #endif /* BUILD_YM2612 */
                   3281: 
                   3282: 
                   3283: 
                   3284: #if BUILD_YM2151
                   3285: /*******************************************************************************/
                   3286: /*      YM2151 local section                                                   */
                   3287: /*******************************************************************************/
                   3288: /* -------------------------- OPM ---------------------------------- */
                   3289: #undef SEG_SUPPORT      /* OPM has not SEG type envelope */
                   3290: 
                   3291: static YM2151 *FMOPM=NULL;  /* array of YM2151's */
                   3292: 
                   3293: /* ---------- priscaler set(and make time tables) ---------- */
                   3294: void OPMInitTable( int num )
                   3295: {
                   3296:     YM2151 *OPM = &(FMOPM[num]);
                   3297:     int i;
                   3298:     double pom;
                   3299:     double rate;
                   3300: 
                   3301:     if (FMOPM[num].ST.rate)
                   3302:         rate = (double)(1<<FREQ_BITS) / (3579545.0 / FMOPM[num].ST.clock * FMOPM[num].ST.rate);
                   3303:     else rate = 1;
                   3304: 
                   3305:     for (i=0; i<8*12*64+950; i++)
                   3306:     {
                   3307:         /* This calculation type was used from the Jarek's YM2151 emulator */
                   3308:         pom = 6.875 * pow (2, ((i+4*64)*1.5625/1200.0) ); /*13.75Hz is note A 12semitones below A-0, so D#0 is 4 semitones above then*/
                   3309:         /*calculate phase increment for above precounted Hertz value*/
                   3310:         OPM->KC_TABLE[i] = (unsigned int)(pom * rate);
                   3311:         /*Log(LOG_WAR,"OPM KC %d = %x\n",i,OPM->KC_TABLE[i]);*/
                   3312:     }
                   3313: 
                   3314:     /* make time tables */
                   3315:     init_timetables( &OPM->ST , OPM_DTTABLE , OPM_ARRATE , OPM_DRRATE );
                   3316: }
                   3317: 
                   3318: /* ---------- reset one of chip ---------- */
                   3319: void OPMResetChip(int num)
                   3320: {
                   3321:     int i;
                   3322:     YM2151 *OPM = &(FMOPM[num]);
                   3323: 
                   3324:     OPMInitTable( num );
                   3325:     reset_channel( &OPM->ST , &OPM->CH[0] , 8 );
                   3326:     /* status clear */
                   3327:     FM_IRQMASK_SET(&OPM->ST,0x03);
                   3328:     OPMWriteReg(num,0x1b,0x00);
                   3329:     /* reset OPerator paramater */
                   3330:     for(i = 0xff ; i >= 0x20 ; i-- ) OPMWriteReg(num,i,0);
                   3331: }
                   3332: 
                   3333: /* ----------  Initialize YM2151 emulator(s) ----------    */
                   3334: /* 'num' is the number of virtual YM2151's to allocate     */
                   3335: /* 'rate' is sampling rate and 'bufsiz' is the size of the */
                   3336: /* buffer that should be updated at each interval          */
                   3337: int OPMInit(int num, int clock, int rate,
                   3338:                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
                   3339: {
                   3340:     int i,j;
                   3341: 
                   3342:     if (FMOPM) return (-1); /* duplicate init. */
                   3343:     cur_chip = NULL;    /* hiro-shi!! */
                   3344: 
                   3345:     FMNumChips = num;
                   3346: 
                   3347:     /* allocate ym2151 state space */
                   3348:     if( (FMOPM = (YM2151 *)malloc(sizeof(YM2151) * FMNumChips))==NULL)
                   3349:         return (-1);
                   3350:     /* allocate total lebel table (128kb space) */
                   3351:     if( !FMInitTable() )
                   3352:     {
                   3353:         free( FMOPM );
                   3354:         return (-1);
                   3355:     }
                   3356:     for ( i = 0 ; i < FMNumChips; i++ ) {
                   3357:         FMOPM[i].ST.index = i;
                   3358:         FMOPM[i].ST.clock = clock;
                   3359:         FMOPM[i].ST.rate = rate;
                   3360:         /* FMOPM[i].ST.irq  = 0; */
                   3361:         /* FMOPM[i].ST.status = 0; */
                   3362:         FMOPM[i].ST.timermodel = FM_TIMER_SINGLE;
                   3363:         FMOPM[i].ST.freqbase  = rate ? ((double)clock * 4096.0 / rate) / 64 : 0;
                   3364:         FMOPM[i].ST.TimerBase = rate ? 1.0/((double)clock / 64.0) : 0;
                   3365:         /*OPMSetBuffer(i,0,0);*/
                   3366:         /* Extend handler */
                   3367:         FMOPM[i].ST.Timer_Handler = TimerHandler;
                   3368:         FMOPM[i].ST.IRQ_Handler   = IRQHandler;
                   3369:         /* Reset callback handler of CT0/1 */
                   3370:         FMOPM[i].PortWrite = 0;
                   3371:         OPMResetChip(i);
                   3372:     }
                   3373:     return(0);
                   3374: }
                   3375: 
                   3376: /* ---------- shut down emurator ----------- */
                   3377: void OPMShutdown()
                   3378: {
                   3379:     if (!FMOPM) return;
                   3380: 
                   3381:     FMCloseTable();
                   3382:     free(FMOPM);
                   3383:     FMOPM = NULL;
                   3384: }
                   3385: /* ---------- write a register on YM2151 chip number 'n' ---------- */
                   3386: void OPMWriteReg(int n, int r, int v)
                   3387: {
                   3388:     unsigned char c;
                   3389:     FM_CH *CH;
                   3390:     FM_SLOT *SLOT;
                   3391: 
                   3392:     YM2151 *OPM = &(FMOPM[n]);
                   3393: 
                   3394:     c   = OPM_CHAN(r);
                   3395:     CH  = &OPM->CH[c];
                   3396:     SLOT= &CH->SLOT[OPM_SLOT(r)];
                   3397: 
                   3398:     switch( r & 0xe0 ){
                   3399:     case 0x00: /* 0x00-0x1f */
                   3400:         switch( r ){
                   3401:         case 0x01:  /* test */
                   3402:             break;
                   3403:         case 0x08:  /* key on / off */
                   3404:             c = v&7;
                   3405:             /* CSM mode */
                   3406:             if( c == 7 && (OPM->ST.mode & 0x80) ) break;
                   3407:             CH = &OPM->CH[c];
                   3408:             if(v&0x08) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
                   3409:             if(v&0x10) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
                   3410:             if(v&0x20) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
                   3411:             if(v&0x40) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
                   3412:             break;
                   3413:         case 0x0f:  /* Noise freq (ch7.op4) */
                   3414:             /* b7 = Noise enable */
                   3415:             /* b0-4 noise freq  */
                   3416:             if( v & 0x80 ){
                   3417:                 /* !!!!! do not supported noise mode  !!!!! */
                   3418:                 Log(LOG_WAR,"OPM Noise mode sel ( not supported )\n");
                   3419:             }
                   3420:             OPM->NReg = v & 0x8f;
                   3421:             break;
                   3422:         case 0x10:  /* timer A High 8*/
                   3423:             OPM->ST.TA = (OPM->ST.TA & 0x03)|(((int)v)<<2);
                   3424:             break;
                   3425:         case 0x11:  /* timer A Low 2*/
                   3426:             OPM->ST.TA = (OPM->ST.TA & 0x3fc)|(v&3);
                   3427:             break;
                   3428:         case 0x12:  /* timer B */
                   3429:             OPM->ST.TB = v;
                   3430:             break;
                   3431:         case 0x14:  /* mode , timer controll */
                   3432:             FMSetMode( &(OPM->ST),n,v );
                   3433:             break;
                   3434:         case 0x18:  /* lfreq   */
                   3435:             /* !!!!! pickup lfo frequency table !!!!! */
                   3436:             break;
                   3437:         case 0x19:  /* PMD/AMD */
                   3438:             if( v & 0x80 ) OPM->pmd = v & 0x7f;
                   3439:             else           OPM->amd = v & 0x7f;
                   3440:             break;
                   3441:         case 0x1b:  /* CT , W  */
                   3442:             /* b7 = CT1 */
                   3443:             /* b6 = CT0 */
                   3444:             /* b0-3 = wave form(LFO) 0=nokogiri,1=houkei,2=sankaku,3=noise */
                   3445:             OPM->ctw = v&0xff;
                   3446:             if( OPM->PortWrite != 0)
                   3447:                 OPM->PortWrite(0, (OPM->ctw)>>6 ); /* bit0 = CT0,bit1 = CT1 */
                   3448:             break;
                   3449:         }
                   3450:         break;
                   3451:     case 0x20:  /* 20-3f */
                   3452:         switch( OPM_SLOT(r) ){
                   3453:         case 0: /* 0x20-0x27 : RL,FB,CON */
                   3454:             {
                   3455:                 int feedback = (v>>3)&7;
                   3456:                 CH->ALGO = v&7;
                   3457:                 CH->FB  = feedback ? 8 - feedback : 0;
                   3458:                 CH->PAN = ((v>>6)&0x03);
                   3459:                 set_algorythm( CH );
                   3460:             }
                   3461:             break;
                   3462:         case 1: /* 0x28-0x2f : Keycode */
                   3463:             {
                   3464:                 int blk = (v>>4)&7;
                   3465:                 /* make keyscale code */
                   3466:                 CH->kcode = (v>>2)&0x1f;
                   3467:                 /* make basic increment counter 22bit = 1 cycle */
                   3468:                 CH->fc = (blk * (12*64)) + KC_TO_SEMITONE[v&0x0f] + CH->fn_h;
                   3469:                 CH->SLOT[SLOT1].Incr=-1;
                   3470:             }
                   3471:             break;
                   3472:         case 2: /* 0x30-0x37 : Keyfunction */
                   3473:             CH->fc -= CH->fn_h;
                   3474:             CH->fn_h = v>>2;
                   3475:             CH->fc += CH->fn_h;
                   3476:             CH->SLOT[SLOT1].Incr=-1;
                   3477:             break;
                   3478:         case 3: /* 0x38-0x3f : PMS / AMS */
                   3479:             /* b0-1 AMS */
                   3480:             /* AMS * 23.90625db */
                   3481:             CH->SLOT[SLOT1].ams = v & 0x03;
                   3482:             CH->SLOT[SLOT2].ams = v & 0x03;
                   3483:             CH->SLOT[SLOT3].ams = v & 0x03;
                   3484:             CH->SLOT[SLOT4].ams = v & 0x03;
                   3485:             /* b4-6 PMS */
                   3486:             /* 0,5,10,20,50,100,400,700 (cent) */
                   3487:             CH->SLOT[SLOT1].pms = (v>>4) & 0x07;
                   3488:             CH->SLOT[SLOT2].pms = (v>>4) & 0x07;
                   3489:             CH->SLOT[SLOT3].pms = (v>>4) & 0x07;
                   3490:             CH->SLOT[SLOT4].pms = (v>>4) & 0x07;
                   3491:             break;
                   3492:         }
                   3493:         break;
                   3494:     case 0x40:  /* DT1,MUL */
                   3495:         set_det_mul(&OPM->ST,CH,SLOT,v);
                   3496:         break;
                   3497:     case 0x60:  /* TL */
                   3498:         set_tl(CH,SLOT,v,(c == 7) && (OPM->ST.mode & 0x80) );
                   3499:         break;
                   3500:     case 0x80:  /* KS, AR */
                   3501:         set_ar_ksr(CH,SLOT,v,OPM->ST.AR_TABLE);
                   3502:         break;
                   3503:     case 0xa0:  /* AMS EN,D1R */
                   3504:         /* bit7 = AMS ENABLE */
                   3505:         set_dr(SLOT,v,OPM->ST.DR_TABLE);
                   3506:         break;
                   3507:     case 0xc0:  /* DT2 ,D2R */
                   3508:         SLOT->DT2  = DT2_TABLE[v>>6];
                   3509:         CH->SLOT[SLOT1].Incr=-1;
                   3510:         set_sr(SLOT,v,OPM->ST.DR_TABLE);
                   3511:         break;
                   3512:     case 0xe0:  /* D1L, RR */
                   3513:         set_sl_rr(SLOT,v,OPM->ST.DR_TABLE);
                   3514:         break;
                   3515:     }
                   3516: }
                   3517: 
                   3518: /* ---------- read status port ---------- */
                   3519: unsigned char OPMReadStatus(int n)
                   3520: {
                   3521:     return FMOPM[n].ST.status;
                   3522: }
                   3523: 
                   3524: int YM2151Write(int n,int a,int v)
                   3525: {
                   3526:     YM2151 *F2151 = &(FMOPM[n]);
                   3527: 
                   3528:     if( !(a&1) )
                   3529:     {   /* address port */
                   3530:         F2151->ST.address = v & 0xff;
                   3531:     }
                   3532:     else
                   3533:     {   /* data port */
                   3534:         int addr = F2151->ST.address;
                   3535:         YM2151UpdateReq(n);
                   3536:         /* write register */
                   3537:          OPMWriteReg(n,addr,v);
                   3538:     }
                   3539:     return F2151->ST.irq;
                   3540: }
                   3541: 
                   3542: unsigned char YM2151Read(int n,int a)
                   3543: {
                   3544:     if( !(a&1) ) return 0;
                   3545:     else         return FMOPM[n].ST.status;
                   3546: }
                   3547: 
                   3548: /* ---------- make digital sound data ---------- */
                   3549: void OPMUpdateOne(int num, void **buffer, int length)
                   3550: {
                   3551:     YM2151 *OPM = &(FMOPM[num]);
                   3552:     int i,ch;
                   3553:     int dataR,dataL;
                   3554: 
                   3555:     /* set bufer */
                   3556:     bufL = (FMSAMPLE *)buffer[0];
                   3557:     bufR = (FMSAMPLE *)buffer[1];
                   3558: 
                   3559:     if( (void *)OPM != cur_chip ){
                   3560:         cur_chip = (void *)OPM;
                   3561: 
                   3562:         State = &OPM->ST;
                   3563:         /* channel pointer */
                   3564:         cch[0] = &OPM->CH[0];
                   3565:         cch[1] = &OPM->CH[1];
                   3566:         cch[2] = &OPM->CH[2];
                   3567:         cch[3] = &OPM->CH[3];
                   3568:         cch[4] = &OPM->CH[4];
                   3569:         cch[5] = &OPM->CH[5];
                   3570:         cch[6] = &OPM->CH[6];
                   3571:         cch[7] = &OPM->CH[7];
                   3572:     }
                   3573:     OPM_CALC_FCOUNT( OPM , cch[0] );
                   3574:     OPM_CALC_FCOUNT( OPM , cch[1] );
                   3575:     OPM_CALC_FCOUNT( OPM , cch[2] );
                   3576:     OPM_CALC_FCOUNT( OPM , cch[3] );
                   3577:     OPM_CALC_FCOUNT( OPM , cch[4] );
                   3578:     OPM_CALC_FCOUNT( OPM , cch[5] );
                   3579:     OPM_CALC_FCOUNT( OPM , cch[6] );
                   3580:     /* CSM check */
                   3581:     OPM_CALC_FCOUNT( OPM , cch[7] );
                   3582: 
                   3583:     for( i=0; i < length ; i++ )
                   3584:     {
                   3585:         /* clear output acc. */
                   3586:         outd[OPM_LEFT] = outd[OPM_RIGHT]= outd[OPM_CENTER] = 0;
                   3587:         /* calcrate channel output */
                   3588:         for( ch=0;ch<8;ch++) FM_CALC_CH( cch[ch] );
                   3589:         /* get left & right output */
                   3590:         dataL = Limit( outd[OPM_CENTER] + outd[OPM_LEFT], OPM_MAXOUT, OPM_MINOUT );
                   3591:         dataR = Limit( outd[OPM_CENTER] + outd[OPM_RIGHT], OPM_MAXOUT, OPM_MINOUT );
                   3592: 
                   3593: #ifdef FM_STEREO_MIX        /* stereo mixing */
                   3594:         /* stereo mix */
                   3595:         ((FMSAMPLE_MIX *)bufL)[i] = ((dataL>>OPM_OUTSB)<<FM_OUTPUT_BIT)|(dataR>>OPM_OUTSB);
                   3596: #else
                   3597:         /* stereo separate */
                   3598:         bufL[i] = dataL>>OPM_OUTSB;
                   3599:         bufR[i] = dataR>>OPM_OUTSB;
                   3600: #endif
                   3601: #ifdef LFO_SUPPORT
                   3602:         CALC_LOPM_LFO;
                   3603: #endif
                   3604: 
                   3605: #ifdef INTERNAL_TIMER
                   3606:         CALC_TIMER_A( State , cch[7] );
                   3607: #endif
                   3608:     }
                   3609: #ifdef INTERNAL_TIMER
                   3610:     CALC_TIMER_B( State , length );
                   3611: #endif
                   3612: }
                   3613: 
                   3614: void OPMSetPortHander(int n,void (*PortWrite)(int offset,int CT) )
                   3615: {
                   3616:     FMOPM[n].PortWrite = PortWrite;
                   3617: }
                   3618: 
                   3619: #if 0
                   3620: /* ---------- return the buffer ---------- */
                   3621: FMSAMPLE *OPMBuffer(int n,int c)
                   3622: {
                   3623:     return FMOPM[n].Buf[c];
                   3624: }
                   3625: /* ---------- set buffer ---------- */
                   3626: int OPMSetBuffer(int n, FMSAMPLE **buf )
                   3627: {
                   3628:     int i;
                   3629:     for( i = 0 ; i < YM2151_NUMBUF ; i++){
                   3630:         FMOPM[n].Buf[i] = buf[i];
                   3631:         if( cur_chip == &FMOPM[n] ) cur_chip = NULL;
                   3632:     }
                   3633:     return 0;
                   3634: }
                   3635: #endif
                   3636: 
                   3637: int YM2151TimerOver(int n,int c)
                   3638: {
                   3639:     YM2151 *F2151 = &(FMOPM[n]);
                   3640: 
                   3641:     if( c )
                   3642:     {   /* Timer B */
                   3643:         TimerBOver( &(F2151->ST) );
                   3644:     }
                   3645:     else
                   3646:     {   /* Timer A */
                   3647:         YM2151UpdateReq(n);
                   3648:         /* timer update */
                   3649:         TimerAOver( &(F2151->ST) );
                   3650:         /* CSM mode key,TL controll */
                   3651:         if( F2151->ST.mode & 0x80 )
                   3652:         {   /* CSM mode total level latch and auto key on */
                   3653:             CSMKeyControll( &(F2151->CH[7]) );
                   3654:         }
                   3655:     }
                   3656:     return F2151->ST.irq;
                   3657: }
                   3658: 
                   3659: #endif /* BUILD_YM2151 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.