Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 1
/*
2
**
3
** File: fm.c -- software implementation of Yamaha FM sound generator
4
**
5
** Copyright (C) 2001, 2002, 2003 Jarek Burczynski (bujar at mame dot net)
6
** Copyright (C) 1998 Tatsuyuki Satoh , MultiArcadeMachineEmulator development
7
**
8
** Version 1.4A (final beta)
9
**
10
*/
11
 
12
/*
13
** History:
14
**
15
** 14-02-2006 Alone Coder:
16
**  - fixed YM2203 stop volume (511 instead of MAX_ATT_INDEX) - verified on real chip
17
**  - fixed YM2203 SSG-EG=#0a key off (inversion disabled) - verified on real chip
18
**  - uncommented sine generator in SSG-EG reinit - verified on real chip
19
**
20
** 03-08-2003 Jarek Burczynski:
21
**  - fixed YM2608 initial values (after the reset)
22
**  - fixed flag and irqmask handling (YM2608)
23
**  - fixed BUFRDY flag handling (YM2608)
24
**
25
** 14-06-2003 Jarek Burczynski:
26
**  - implemented all of the YM2608 status register flags
27
**  - implemented support for external memory read/write via YM2608
28
**  - implemented support for deltat memory limit register in YM2608 emulation
29
**
30
** 22-05-2003 Jarek Burczynski:
31
**  - fixed LFO PM calculations (copy&paste bugfix)
32
**
33
** 08-05-2003 Jarek Burczynski:
34
**  - fixed SSG support
35
**
36
** 22-04-2003 Jarek Burczynski:
37
**  - implemented 100% correct LFO generator (verified on real YM2610 and YM2608)
38
**
39
** 15-04-2003 Jarek Burczynski:
40
**  - added support for YM2608's register 0x110 - status mask
41
**
42
** 01-12-2002 Jarek Burczynski:
43
**  - fixed register addressing in YM2608, YM2610, YM2610B chips. (verified on real YM2608)
44
**    The addressing patch used for early Neo-Geo games can be removed now.
45
**
46
** 26-11-2002 Jarek Burczynski, Nicola Salmoria:
47
**  - recreated YM2608 ADPCM ROM using data from real YM2608's output which leads to:
48
**  - added emulation of YM2608 drums.
49
**  - output of YM2608 is two times lower now - same as YM2610 (verified on real YM2608)
50
**
51
** 16-08-2002 Jarek Burczynski:
52
**  - binary exact Envelope Generator (verified on real YM2203);
53
**    identical to YM2151
54
**  - corrected 'off by one' error in feedback calculations (when feedback is off)
55
**  - corrected connection (algorithm) calculation (verified on real YM2203 and YM2610)
56
**
57
** 18-12-2001 Jarek Burczynski:
58
**  - added SSG-EG support (verified on real YM2203)
59
**
60
** 12-08-2001 Jarek Burczynski:
61
**  - corrected sin_tab and tl_tab data (verified on real chip)
62
**  - corrected feedback calculations (verified on real chip)
63
**  - corrected phase generator calculations (verified on real chip)
64
**  - corrected envelope generator calculations (verified on real chip)
65
**  - corrected FM volume level (YM2610 and YM2610B).
66
**  - changed YMxxxUpdateOne() functions (YM2203, YM2608, YM2610, YM2610B, YM2612) :
67
**    this was needed to calculate YM2610 FM channels output correctly.
68
**    (Each FM channel is calculated as in other chips, but the output of the channel
69
**    gets shifted right by one *before* sending to accumulator. That was impossible to do
70
**    with previous implementation).
71
**
72
** 23-07-2001 Jarek Burczynski, Nicola Salmoria:
73
**  - corrected YM2610 ADPCM type A algorithm and tables (verified on real chip)
74
**
75
** 11-06-2001 Jarek Burczynski:
76
**  - corrected end of sample bug in ADPCMA_calc_cha().
77
**    Real YM2610 checks for equality between current and end addresses (only 20 LSB bits).
78
**
79
** 08-12-98 hiro-shi:
80
** rename ADPCMA -> ADPCMB, ADPCMB -> ADPCMA
81
** move ROM limit check.(CALC_CH? -> 2610Write1/2)
82
** test program (ADPCMB_TEST)
83
** move ADPCM A/B end check.
84
** ADPCMB repeat flag(no check)
85
** change ADPCM volume rate (8->16) (32->48).
86
**
87
** 09-12-98 hiro-shi:
88
** change ADPCM volume. (8->16, 48->64)
89
** replace ym2610 ch0/3 (YM-2610B)
90
** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff.
91
** add ADPCM_SHIFT_MASK
92
** change ADPCMA_DECODE_MIN/MAX.
93
*/
94
 
95
 
96
 
97
 
98
/************************************************************************/
99
/*    comment of hiro-shi(Hiromitsu Shioya)                             */
100
/*    YM2610(B) = OPN-B                                                 */
101
/*    YM2610  : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch      */
102
/*    YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch      */
103
/************************************************************************/
104
 
105
//fnum= fq*2.3575
106
/* globals */
107
#include "std.h"
108
#include "sysdefs.h"
109
#include "emul_2203.h"
110
 
111
#define TYPE_SSG    0x01    /* SSG support          */
112
#define TYPE_LFOPAN 0x02    /* OPN type LFO and PAN */
113
#define TYPE_6CH    0x04    /* FM 6CH / 3CH         */
114
#define TYPE_DAC    0x08    /* YM2612's DAC device  */
115
#define TYPE_ADPCM  0x10    /* two ADPCM units      */
116
 
117
#define TYPE_YM2203 (TYPE_SSG)
118
#define TYPE_YM2608 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
119
#define TYPE_YM2610 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
120
#define TYPE_YM2612 (TYPE_DAC |TYPE_LFOPAN |TYPE_6CH)
121
 
122
#define FREQ_SH                 16  /* 16.16 fixed point (frequency calculations) */
123
#define EG_SH                   16  /* 16.16 fixed point (envelope generator timing) */
124
#define LFO_SH                  24  /*  8.24 fixed point (LFO calculations)       */
125
#define TIMER_SH                16  /* 16.16 fixed point (timers calculations)    */
126
 
127
#define FREQ_MASK               ((1<<FREQ_SH)-1)
128
 
129
#define ENV_BITS                10
130
#define ENV_LEN                 (1<<ENV_BITS)
131
#define ENV_STEP                (128.0/ENV_LEN)
132
 
133
#define MAX_ATT_INDEX   (ENV_LEN-1) /* 1023 */
134
#define MIN_ATT_INDEX   (0)                     /* 0 */
135
 
136
#define EG_ATT                  4
137
#define EG_DEC                  3
138
#define EG_SUS                  2
139
#define EG_REL                  1
140
#define EG_OFF                  0
141
 
142
#define SIN_BITS                10
143
#define SIN_LEN                 (1<<SIN_BITS)
144
#define SIN_MASK                (SIN_LEN-1)
145
 
146
#define TL_RES_LEN              (256) /* 8 bits addressing (real chip) */
147
 
148
#if (FM_SAMPLE_BITS==16)
149
        #define FINAL_SH        (0)
150
        #define MAXOUT          (+32767)
151
        #define MINOUT          (-32768)
152
#else
153
        #define FINAL_SH        (8)
154
        #define MAXOUT          (+127)
155
        #define MINOUT          (-128)
156
#endif
157
 
158
/*  TL_TAB_LEN is calculated as:
159
*   13 - sinus amplitude bits     (Y axis)
160
*   2  - sinus sign bit           (Y axis)
161
*   TL_RES_LEN - sinus resolution (X axis)
162
*/
163
#define TL_TAB_LEN (13*2*TL_RES_LEN)
164
 
165
#define ENV_QUIET               (TL_TAB_LEN>>3)
166
 
167
#define RATE_STEPS (8)
168
 
169
#define INTERNAL_TIMER_A(ST,CSM_CH)
170
#define INTERNAL_TIMER_B(ST,step)
171
 
172
#define logerror(a,b,c,d,e)
173
 
174
#define SC(db) (UINT32) ( db * (4.0/ENV_STEP) )
175
static const UINT32 sl_table[16]={
176
 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
177
 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
178
};
179
#undef SC
180
 
181
static const UINT8 eg_inc[19*RATE_STEPS]={
182
 
183
/*cycle:0 1  2 3  4 5  6 7*/
184
 
185
/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..11 0 (increment by 0 or 1) */
186
/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..11 1 */
187
/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..11 2 */
188
/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..11 3 */
189
 
190
/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 12 0 (increment by 1) */
191
/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 12 1 */
192
/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 12 2 */
193
/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 12 3 */
194
 
195
/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 13 0 (increment by 2) */
196
/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 13 1 */
197
/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 13 2 */
198
/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 13 3 */
199
 
200
/*12 */ 4,4, 4,4, 4,4, 4,4, /* rate 14 0 (increment by 4) */
201
/*13 */ 4,4, 4,8, 4,4, 4,8, /* rate 14 1 */
202
/*14 */ 4,8, 4,8, 4,8, 4,8, /* rate 14 2 */
203
/*15 */ 4,8, 8,8, 4,8, 8,8, /* rate 14 3 */
204
 
205
/*16 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 8) */
206
/*17 */ 16,16,16,16,16,16,16,16, /* rates 15 2, 15 3 for attack */
207
/*18 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */
208
};
209
 
210
#define O(a) (a*RATE_STEPS)
211
 
212
/*note that there is no O(17) in this table - it's directly in the code */
213
static const UINT8 eg_rate_select[32+64+32]={   /* Envelope Generator rates (32 + 64 rates + 32 RKS) */
214
/* 32 infinite time rates */
215
O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
216
O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
217
O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
218
O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
219
 
220
/* rates 00-11 */
221
O( 0),O( 1),O( 2),O( 3),
222
O( 0),O( 1),O( 2),O( 3),
223
O( 0),O( 1),O( 2),O( 3),
224
O( 0),O( 1),O( 2),O( 3),
225
O( 0),O( 1),O( 2),O( 3),
226
O( 0),O( 1),O( 2),O( 3),
227
O( 0),O( 1),O( 2),O( 3),
228
O( 0),O( 1),O( 2),O( 3),
229
O( 0),O( 1),O( 2),O( 3),
230
O( 0),O( 1),O( 2),O( 3),
231
O( 0),O( 1),O( 2),O( 3),
232
O( 0),O( 1),O( 2),O( 3),
233
 
234
/* rate 12 */
235
O( 4),O( 5),O( 6),O( 7),
236
 
237
/* rate 13 */
238
O( 8),O( 9),O(10),O(11),
239
 
240
/* rate 14 */
241
O(12),O(13),O(14),O(15),
242
 
243
/* rate 15 */
244
O(16),O(16),O(16),O(16),
245
 
246
/* 32 dummy rates (same as 15 3) */
247
O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
248
O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
249
O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
250
O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
251
 
252
};
253
#undef O
254
 
255
#define O(a) (a*1)
256
static const UINT8 eg_rate_shift[32+64+32]={    /* Envelope Generator counter shifts (32 + 64 rates + 32 RKS) */
257
/* 32 infinite time rates */
258
O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
259
O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
260
O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
261
O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
262
 
263
/* rates 00-11 */
264
O(11),O(11),O(11),O(11),
265
O(10),O(10),O(10),O(10),
266
O( 9),O( 9),O( 9),O( 9),
267
O( 8),O( 8),O( 8),O( 8),
268
O( 7),O( 7),O( 7),O( 7),
269
O( 6),O( 6),O( 6),O( 6),
270
O( 5),O( 5),O( 5),O( 5),
271
O( 4),O( 4),O( 4),O( 4),
272
O( 3),O( 3),O( 3),O( 3),
273
O( 2),O( 2),O( 2),O( 2),
274
O( 1),O( 1),O( 1),O( 1),
275
O( 0),O( 0),O( 0),O( 0),
276
 
277
/* rate 12 */
278
O( 0),O( 0),O( 0),O( 0),
279
 
280
/* rate 13 */
281
O( 0),O( 0),O( 0),O( 0),
282
 
283
/* rate 14 */
284
O( 0),O( 0),O( 0),O( 0),
285
 
286
/* rate 15 */
287
O( 0),O( 0),O( 0),O( 0),
288
 
289
/* 32 dummy rates (same as 15 3) */
290
O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
291
O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
292
O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
293
O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0)
294
};
295
#undef O
296
 
297
static const UINT8 dt_tab[4 * 32]={
298
/* this is YM2151 and YM2612 phase increment data (in 10.10 fixed point format)*/
299
/* FD=0 */
300
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
301
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
302
/* FD=1 */
303
        0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
304
        2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
305
/* FD=2 */
306
        1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
307
        5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
308
/* FD=3 */
309
        2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
310
        8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
311
};
312
 
313
/* register number to channel number , slot offset */
314
#define OPN_CHAN(N) (N&3)
315
#define OPN_SLOT(N) ((N>>2)&3)
316
 
317
/* slot number */
318
#define SLOT1 0
319
#define SLOT2 2
320
#define SLOT3 1
321
#define SLOT4 3
322
 
323
/* OPN key frequency number -> key code follow table */
324
/* fnum higher 4bit -> keycode lower 2bit */
325
static const UINT8 opn_fktable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
326
 
327
static INT16/*signed int*/ tl_tab[TL_TAB_LEN];
328
 
329
/* sin waveform table in 'decibel' scale */
330
static UINT16/*unsigned int*/ sin_tab[SIN_LEN];
331
 
332
/* current chip state */
333
static void     *_cur_chip = 0; /* pointer of current chip struct */
334
static FM_ST    *_State;                        /* basic status */
335
static FM_CH    *_cch[3];               /* pointer of FM channels */
336
 
337
 
338
static INT32    _m2,_c1,_c2;            /* Phase Modulation input for operators 2,3,4 */
339
static INT32    _mem;                   /* one sample delay memory */
340
 
341
static INT32    _out_fm[3];             /* outputs of working channels */
342
 
343
/* limitter */
344
 
345
#define Limit(val, max,min) { \
346
        if ( val > max )      val = max; \
347
        else if ( val < min ) val = min; \
348
}
349
 
350
/* status set and IRQ handling */
351
void FM_STATUS_SET(FM_ST *ST,int flag)
352
{
353
        /* set status flag */
354
        ST->status |= flag;
355
        if ( !(ST->irq) && (ST->status & ST->irqmask) )
356
        {
357
                ST->irq = 1;
358
                /* callback user interrupt handler (IRQ is OFF to ON) */
359
//              if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->param,1);
360
        }
361
}
362
 
363
/* status reset and IRQ handling */
364
void FM_STATUS_RESET(FM_ST *ST,int flag)
365
{
366
        /* reset status flag */
367
        ST->status &=~flag;
368
        if ( (ST->irq) && !(ST->status & ST->irqmask) )
369
        {
370
                ST->irq = 0;
371
                /* callback user interrupt handler (IRQ is ON to OFF) */
372
//              if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->param,0);
373
        }
374
}
375
 
376
/* IRQ mask set */
377
void FM_IRQMASK_SET(FM_ST *ST,int flag)
378
{
379
        ST->irqmask = flag;
380
        /* IRQ handling check */
381
        FM_STATUS_SET(ST,0);
382
        FM_STATUS_RESET(ST,0);
383
}
384
 
385
 
386
/* OPN Mode Register Write */
387
void set_timers( FM_ST *ST, void *n, int v )
388
{
389
        /* b7 = CSM MODE */
390
        /* b6 = 3 slot mode */
391
        /* b5 = reset b */
392
        /* b4 = reset a */
393
        /* b3 = timer enable b */
394
        /* b2 = timer enable a */
395
        /* b1 = load b */
396
        /* b0 = load a */
397
        ST->mode = v;
398
 
399
        /* reset Timer b flag */
400
        if( v & 0x20 )
401
                FM_STATUS_RESET(ST,0x02);
402
        /* reset Timer a flag */
403
        if( v & 0x10 )
404
                FM_STATUS_RESET(ST,0x01);
405
        /* load b */
406
        if( v & 0x02 )
407
        {
408
                if( ST->TBC == 0 )
409
                {
410
                        ST->TBC = ( 256-ST->TB)<<4;
411
                        /* External timer handler */
412
//                      if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,ST->TBC,ST->TimerBase);
413
                }
414
        }
415
        else
416
        {       /* stop timer b */
417
                if( ST->TBC != 0 )
418
                {
419
                        ST->TBC = 0;
420
//                      if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,0,ST->TimerBase);
421
                }
422
        }
423
        /* load a */
424
        if( v & 0x01 )
425
        {
426
                if( ST->TAC == 0 )
427
                {
428
                        ST->TAC = (1024-ST->TA);
429
                        /* External timer handler */
430
//                      if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,ST->TAC,ST->TimerBase);
431
                }
432
        }
433
        else
434
        {       /* stop timer a */
435
                if( ST->TAC != 0 )
436
                {
437
                        ST->TAC = 0;
438
//                      if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,0,ST->TimerBase);
439
                }
440
        }
441
}
442
 
443
/* Timer A Overflow */
444
void TimerAOver(FM_ST *ST)
445
{
446
        /* set status (if enabled) */
447
        if(ST->mode & 0x04) FM_STATUS_SET(ST,0x01);
448
        /* clear or reload the counter */
449
        ST->TAC = (1024-ST->TA);
450
//      if (ST->Timer_Handler) (ST->Timer_Handler)(ST->param,0,ST->TAC,ST->TimerBase);
451
}
452
/* Timer B Overflow */
453
void TimerBOver(FM_ST *ST)
454
{
455
        /* set status (if enabled) */
456
        if(ST->mode & 0x08) FM_STATUS_SET(ST,0x02);
457
        /* clear or reload the counter */
458
        ST->TBC = ( 256-ST->TB)<<4;
459
//      if (ST->Timer_Handler) (ST->Timer_Handler)(ST->param,1,ST->TBC,ST->TimerBase);
460
}
461
 
462
 
463
#if FM_BUSY_FLAG_SUPPORT
464
UINT8 FM_STATUS_FLAG(FM_ST *ST)
465
{
466
        if( ST->BusyExpire )
467
        {
468
                if( (ST->BusyExpire - FM_GET_TIME_NOW()) > 0)
469
                        return ST->status | 0x80;       /* with busy */
470
                /* expire */
471
                ST->BusyExpire = 0;
472
        }
473
        return ST->status;
474
}
475
void FM_BUSY_SET(FM_ST *ST,int busyclock )
476
{
477
        ST->BusyExpire = FM_GET_TIME_NOW() + (ST->TimerBase * busyclock);
478
}
479
#define FM_BUSY_CLEAR(ST) ((ST)->BusyExpire = 0)
480
#else
481
#define FM_STATUS_FLAG(ST) ((ST)->status)
482
#define FM_BUSY_SET(ST,bclock) {}
483
#define FM_BUSY_CLEAR(ST) {}
484
#endif
485
 
486
 
487
void FM_KEYON(FM_CH *CH , int s )
488
{
489
        FM_SLOT *SLOT = &CH->SLOT[s];
490
        if( !SLOT->key )
491
        {
492
                SLOT->key = 1;
493
                SLOT->phase = 0;                /* restart Phase Generator */ //restored by Alone Coder
494
                SLOT->state = EG_ATT;   /* phase -> Attack */
495
                if ( SLOT->volume >= MAX_ATT_INDEX )SLOT->volume = 511; /* Alone Coder */
496
        }
497
}
498
 
499
void FM_KEYOFF(FM_CH *CH , int s )
500
{
501
        FM_SLOT *SLOT = &CH->SLOT[s];
502
        if( SLOT->key )
503
        {
504
                SLOT->key = 0;
505
                if (SLOT->state>EG_REL)
506
                        SLOT->state = EG_REL;/* phase -> Release */
507
        }
508
}
509
 
510
/* set algorithm connection */
511
static void setup_connection( FM_CH *CH, int ch )
512
{
513
        INT32 *carrier = &_out_fm[ch];
514
 
515
        INT32 **om1 = &CH->connect1;
516
        INT32 **oc1 = &CH->connect2;
517
        INT32 **om2 = &CH->connect3;
518
        INT32 **memc = &CH->mem_connect;
519
 
520
        switch( CH->ALGO ){
521
        case 0:
522
                /* M1---C1---MEM---M2---C2---OUT */
523
                *om1 = &_c1;
524
                *oc1 = &_mem;
525
                *om2 = &_c2;
526
                *memc= &_m2;
527
                break;
528
        case 1:
529
                /* M1------+-MEM---M2---C2---OUT */
530
                /*      C1-+                     */
531
                *om1 = &_mem;
532
                *oc1 = &_mem;
533
                *om2 = &_c2;
534
                *memc= &_m2;
535
                break;
536
        case 2:
537
                /* M1-----------------+-C2---OUT */
538
                /*      C1---MEM---M2-+          */
539
                *om1 = &_c2;
540
                *oc1 = &_mem;
541
                *om2 = &_c2;
542
                *memc= &_m2;
543
                break;
544
        case 3:
545
                /* M1---C1---MEM------+-C2---OUT */
546
                /*                 M2-+          */
547
                *om1 = &_c1;
548
                *oc1 = &_mem;
549
                *om2 = &_c2;
550
                *memc= &_c2;
551
                break;
552
        case 4:
553
                /* M1---C1-+-OUT */
554
                /* M2---C2-+     */
555
                /* MEM: not used */
556
                *om1 = &_c1;
557
                *oc1 = carrier;
558
                *om2 = &_c2;
559
                *memc= &_mem;   /* store it anywhere where it will not be used */
560
                break;
561
        case 5:
562
                /*    +----C1----+     */
563
                /* M1-+-MEM---M2-+-OUT */
564
                /*    +----C2----+     */
565
                *om1 = 0;       /* special mark */
566
                *oc1 = carrier;
567
                *om2 = carrier;
568
                *memc= &_m2;
569
                break;
570
        case 6:
571
                /* M1---C1-+     */
572
                /*      M2-+-OUT */
573
                /*      C2-+     */
574
                /* MEM: not used */
575
                *om1 = &_c1;
576
                *oc1 = carrier;
577
                *om2 = carrier;
578
                *memc= &_mem;   /* store it anywhere where it will not be used */
579
                break;
580
        case 7:
581
                /* M1-+     */
582
                /* C1-+-OUT */
583
                /* M2-+     */
584
                /* C2-+     */
585
                /* MEM: not used*/
586
                *om1 = carrier;
587
                *oc1 = carrier;
588
                *om2 = carrier;
589
                *memc= &_mem;   /* store it anywhere where it will not be used */
590
                break;
591
        }
592
 
593
        CH->connect4 = carrier;
594
}
595
 
596
/* set detune & multiple #3x */
597
void set_det_mul(FM_ST *ST,FM_CH *CH,FM_SLOT *SLOT,int v)
598
{
599
        SLOT->mul = (v&0x0f)? (v&0x0f)*2 : 1;
600
        SLOT->DT  = ST->dt_tab[(v>>4)&7];
601
        CH->SLOT[SLOT1].Incr=-1;
602
}
603
 
604
/* set total level #4x*/
605
void set_tl(FM_CH *CH,FM_SLOT *SLOT , int v)
606
{
607
        SLOT->tl = (v&0x7f)<<(ENV_BITS-7); /* 7bit TL */
608
}
609
 
610
/* set attack rate & key scale #5x */
611
void set_ar_ksr(FM_CH *CH,FM_SLOT *SLOT,int v)
612
{
613
        UINT8 old_KSR = SLOT->KSR;
614
 
615
        SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
616
 
617
        SLOT->KSR = 3-(v>>6);
618
        if (SLOT->KSR != old_KSR)
619
        {
620
                CH->SLOT[SLOT1].Incr=-1;
621
        }
622
        else
623
        {
624
                /* refresh Attack rate */
625
                if ((SLOT->ar + SLOT->ksr) < 32+62)
626
                {
627
                        SLOT->eg_sh_ar  = eg_rate_shift [SLOT->ar  + SLOT->ksr ];
628
                        SLOT->eg_sel_ar = eg_rate_select[SLOT->ar  + SLOT->ksr ];
629
                }
630
                else
631
                {
632
                        SLOT->eg_sh_ar  = 0;
633
                        SLOT->eg_sel_ar = 17*RATE_STEPS;
634
                }
635
        }
636
}
637
 
638
/* set decay rate  #6x*/
639
void set_dr(FM_SLOT *SLOT,int v)
640
{
641
        SLOT->d1r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
642
 
643
        SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];
644
        SLOT->eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr];
645
 
646
}
647
 
648
/* set sustain rate  #7x*/
649
void set_sr(FM_SLOT *SLOT,int v)
650
{
651
        SLOT->d2r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
652
 
653
        SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];
654
        SLOT->eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr];
655
}
656
 
657
/* set release rate  #8x*/
658
void set_sl_rr(FM_SLOT *SLOT,int v)
659
{
660
        SLOT->sl = sl_table[ v>>4 ];
661
 
662
        SLOT->rr  = 34 + ((v&0x0f)<<2);
663
 
664
        SLOT->eg_sh_rr  = eg_rate_shift [SLOT->rr  + SLOT->ksr];
665
        SLOT->eg_sel_rr = eg_rate_select[SLOT->rr  + SLOT->ksr];
666
}
667
 
668
signed int op_calc(UINT32 phase, unsigned int env, signed int pm)
669
{
670
        UINT32 p;
671
 
672
        p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + (pm<<15))) >> FREQ_SH ) & SIN_MASK ];
673
 
674
        if (p >= TL_TAB_LEN)
675
                return 0;
676
        return tl_tab[p];
677
}
678
 
679
signed int op_calc1(UINT32 phase, unsigned int env, signed int pm)
680
{
681
        UINT32 p;
682
 
683
        p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + pm      )) >> FREQ_SH ) & SIN_MASK ];
684
 
685
        if (p >= TL_TAB_LEN)
686
                return 0;
687
        return tl_tab[p];
688
}
689
 
690
 
691
void chan_calc(FM_OPN *OPN, FM_CH *CH)
692
{
693
        unsigned int eg_out;
694
 
695
        UINT32 AM = 0;//LFO_AM >> CH->ams;
696
 
697
        _m2 = _c1 = _c2 = _mem = 0;
698
 
699
        *CH->mem_connect = CH->mem_value;       /* restore delayed sample (MEM) value to _m2 or _c2 */
700
 
701
        eg_out = CH->SLOT[SLOT1].vol_out;
702
        {
703
                INT32 out = CH->op1_out[0] + CH->op1_out[1];
704
                CH->op1_out[0] = CH->op1_out[1];
705
 
706
                if( !CH->connect1 ){
707
                        /* algorithm 5  */
708
                        _mem = _c1 = _c2 = CH->op1_out[0];
709
                }else{
710
                        /* other algorithms */
711
                        *CH->connect1 += CH->op1_out[0];
712
                }
713
 
714
                CH->op1_out[1] = 0;
715
                if( eg_out < ENV_QUIET )        /* SLOT 1 */
716
                {
717
                        if (!CH->FB)
718
                                out=0;
719
 
720
                        CH->op1_out[1] = op_calc1(CH->SLOT[SLOT1].phase, eg_out, (out<<CH->FB) );
721
                }
722
        }
723
 
724
        eg_out = CH->SLOT[SLOT3].vol_out;
725
        if( eg_out < ENV_QUIET )                /* SLOT 3 */
726
                *CH->connect3 += op_calc(CH->SLOT[SLOT3].phase, eg_out, _m2);
727
 
728
        eg_out = CH->SLOT[SLOT2].vol_out;
729
        if( eg_out < ENV_QUIET )                /* SLOT 2 */
730
                *CH->connect2 += op_calc(CH->SLOT[SLOT2].phase, eg_out, _c1);
731
 
732
        eg_out = CH->SLOT[SLOT4].vol_out;
733
        if( eg_out < ENV_QUIET )                /* SLOT 4 */
734
                *CH->connect4 += op_calc(CH->SLOT[SLOT4].phase, eg_out, _c2);
735
 
736
 
737
        /* store current MEM */
738
        CH->mem_value = _mem;
739
 
740
        /* update phase counters AFTER output calculations */
741
        CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr;
742
        CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr;
743
        CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr;
744
        CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr;
745
}
746
 
747
 
748
/* update phase increment and envelope generator */
749
void refresh_fc_eg_slot(FM_SLOT *SLOT , int fc , int kc )
750
{
751
        int ksr;
752
 
753
        /* (frequency) phase increment counter */
754
        SLOT->Incr = ((fc+SLOT->DT[kc])*SLOT->mul) >> 1;
755
 
756
        ksr = kc >> SLOT->KSR;
757
        if( SLOT->ksr != ksr )
758
        {
759
                SLOT->ksr = ksr;
760
 
761
                /* calculate envelope generator rates */
762
                if ((SLOT->ar + SLOT->ksr) < 32+62)
763
                {
764
                        SLOT->eg_sh_ar  = eg_rate_shift [SLOT->ar  + SLOT->ksr ];
765
                        SLOT->eg_sel_ar = eg_rate_select[SLOT->ar  + SLOT->ksr ];
766
                }
767
                else
768
                {
769
                        SLOT->eg_sh_ar  = 0;
770
                        SLOT->eg_sel_ar = 17*RATE_STEPS;
771
                }
772
 
773
                SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];
774
                SLOT->eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr];
775
 
776
                SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];
777
                SLOT->eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr];
778
 
779
                SLOT->eg_sh_rr  = eg_rate_shift [SLOT->rr  + SLOT->ksr];
780
                SLOT->eg_sel_rr = eg_rate_select[SLOT->rr  + SLOT->ksr];
781
        }
782
}
783
 
784
/* update phase increment counters */
785
void refresh_fc_eg_chan(FM_CH *CH )
786
{
787
        if( CH->SLOT[SLOT1].Incr==-1){
788
                int fc = CH->fc;
789
                int kc = CH->kcode;
790
                refresh_fc_eg_slot(&CH->SLOT[SLOT1] , fc , kc );
791
                refresh_fc_eg_slot(&CH->SLOT[SLOT2] , fc , kc );
792
                refresh_fc_eg_slot(&CH->SLOT[SLOT3] , fc , kc );
793
                refresh_fc_eg_slot(&CH->SLOT[SLOT4] , fc , kc );
794
        }
795
}
796
 
797
/* initialize time tables */
798
static void init_timetables( FM_ST *ST , const UINT8 *dttable )
799
{
800
        int i,d;
801
        double rate;
802
 
803
#if 0
804
        logerror("FM.C: samplerate=%8i chip clock=%8i  freqbase=%f  \n",
805
                         ST->rate, ST->clock, ST->freqbase );
806
#endif
807
 
808
        /* DeTune table */
809
        for (d = 0;d <= 3;d++){
810
                for (i = 0;i <= 31;i++){
811
                        rate = ((double)dttable[d*32 + i]) * SIN_LEN  * ST->freqbase  * (1<<FREQ_SH) / ((double)(1<<20));
812
                        ST->dt_tab[d][i]   = (INT32) rate;
813
                        ST->dt_tab[d+4][i] = -(INT32) rate;
814
#if 0
815
                        logerror("FM.C: DT [%2i %2i] = %8x  \n", d, i, ST->dt_tab[d][i] );
816
#endif
817
                }
818
        }
819
 
820
}
821
 
822
static void reset_channels( FM_ST *ST , FM_CH *CH , int num )
823
{
824
        int c,s;
825
 
826
        ST->mode   = 0; /* normal mode */
827
        ST->TA     = 0;
828
        ST->TAC    = 0;
829
        ST->TB     = 0;
830
        ST->TBC    = 0;
831
 
832
        for( c = 0 ; c < num ; c++ )
833
        {
834
                CH[c].fc = 0;
835
                for(s = 0 ; s < 4 ; s++ )
836
                {
837
                        CH[c].SLOT[s].ssg = 0;
838
                        CH[c].SLOT[s].ssgn = 0;
839
                        CH[c].SLOT[s].state= EG_OFF;
840
                        CH[c].SLOT[s].volume = MAX_ATT_INDEX;
841
                        CH[c].SLOT[s].vol_out= MAX_ATT_INDEX;
842
                }
843
        }
844
}
845
 
846
/* initialize generic tables */
847
static int init_tables(void)
848
{
849
        signed int i,x;
850
        signed int n;
851
        double o,m;
852
 
853
        for (x=0; x<TL_RES_LEN; x++)
854
        {
855
                m = (1<<16) / pow((double)2, (double)((x+1) * (ENV_STEP/4.0) / 8.0));
856
                m = floor(m);
857
 
858
                /* we never reach (1<<16) here due to the (x+1) */
859
                /* result fits within 16 bits at maximum */
860
 
861
                n = (int)m;             /* 16 bits here */
862
                n >>= 4;                /* 12 bits here */
863
                if (n&1)                /* round to nearest */
864
                        n = (n>>1)+1;
865
                else
866
                        n = n>>1;
867
                                                /* 11 bits here (rounded) */
868
                n <<= 2;                /* 13 bits here (as in real chip) */
869
                tl_tab[ x*2 + 0 ] = n;
870
                tl_tab[ x*2 + 1 ] = -n;
871
 
872
                for (i=1; i<13; i++)
873
                {
874
                        tl_tab[ x*2+0 + i*2*TL_RES_LEN ] =  n>>i;
875
                        tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -(n>>i);
876
                }
877
        }
878
        /*logerror("FM.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
879
 
880
 
881
        for (i=0; i<SIN_LEN; i++)
882
        {
883
                /* non-standard sinus */
884
                m = sin( ((i*2)+1) * PI / SIN_LEN ); /* checked against the real chip */
885
 
886
                /* we never reach zero here due to ((i*2)+1) */
887
                if (m>0.0)
888
                        o = 8*(double)log(1.0/m)/log((double)2);        /* convert to 'decibels' */
889
                else
890
                        o = 8*(double)log(-1.0/m)/log((double)2);       /* convert to 'decibels' */
891
 
892
                o = o / (ENV_STEP/4);
893
 
894
                n = (int)(2.0*o);
895
                if (n&1)                                                /* round to nearest */
896
                        n = (n>>1)+1;
897
                else
898
                        n = n>>1;
899
 
900
                sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
901
//              printf("FM.C: sin [%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[i],tl_tab[sin_tab[i]]);
902
        }
903
 
904
        /*logerror("FM.C: ENV_QUIET= %08x\n",ENV_QUIET );*/
905
 
906
        return 1;
907
}
908
 
909
static void FMCloseTable( void )
910
{
911
#ifdef SAVE_SAMPLE
912
//      fclose(sample[0]);
913
#endif
914
        return;
915
}
916
 
917
/* CSM Key Controll */
918
void CSMKeyControll(FM_CH *CH)
919
{
920
        /* this is wrong, atm */
921
 
922
        /* all key on */
923
        FM_KEYON(CH,SLOT1);
924
        FM_KEYON(CH,SLOT2);
925
        FM_KEYON(CH,SLOT3);
926
        FM_KEYON(CH,SLOT4);
927
}
928
 
929
 
930
__inline void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT)
931
{
932
        unsigned int out;
933
        unsigned int swap_flag = 0;
934
        unsigned int i;
935
 
936
 
937
        i = 4; /* four operators per channel */
938
        do
939
        {
940
                switch(SLOT->state)
941
                {
942
                case EG_ATT:            /* attack phase */
943
                        if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_ar)-1) ) )
944
                        {
945
                                SLOT->volume += (~SLOT->volume *
946
                                  (eg_inc[SLOT->eg_sel_ar + ((OPN->eg_cnt>>SLOT->eg_sh_ar)&7)])
947
                                ) >>4;
948
 
949
                                if (SLOT->volume <= MIN_ATT_INDEX)
950
                                {
951
                                        SLOT->volume = MIN_ATT_INDEX;
952
                                        SLOT->state = EG_DEC;
953
                                }
954
                        }
955
                break;
956
 
957
                case EG_DEC:    /* decay phase */
958
                        if (SLOT->ssg&0x08)     /* SSG EG type envelope selected */
959
                        {
960
                                if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
961
                                {
962
                                        SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
963
 
964
                                        if ( (UINT32)SLOT->volume >= SLOT->sl )
965
                                                SLOT->state = EG_SUS;
966
                                }
967
                        }
968
                        else
969
                        {
970
                                if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
971
                                {
972
                                        SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
973
 
974
                                        if ( (UINT32)SLOT->volume >= SLOT->sl )
975
                                                SLOT->state = EG_SUS;
976
                                }
977
                        }
978
                break;
979
 
980
                case EG_SUS:    /* sustain phase */
981
                        if (SLOT->ssg&0x08)     /* SSG EG type envelope selected */
982
                        {
983
                                if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d2r)-1) ) )
984
                                {
985
                                        SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
986
 
987
                                        if ( SLOT->volume >= 512 /* áûëî MAX_ATT_INDEX */ ) //Alone Coder
988
                                        {
989
                                                SLOT->volume = MAX_ATT_INDEX;
990
 
991
                                                if (SLOT->ssg&0x01)     /* bit 0 = hold */
992
                                                {
993
                                                        if (SLOT->ssgn&1)       /* have we swapped once ??? */
994
                                                        {
995
                                                                /* yes, so do nothing, just hold current level */
996
                                                        }
997
                                                        else
998
                                                                swap_flag = (SLOT->ssg&0x02) | 1 ; /* bit 1 = alternate */
999
 
1000
                                                }
1001
                                                else
1002
                                                {
1003
                                                        /* same as KEY-ON operation */
1004
 
1005
                                                        /* restart of the Phase Generator should be here,
1006
                                only if AR is not maximum ??? ALWAYS! */
1007
                                                        SLOT->phase = 0; //Alone Coder
1008
 
1009
                                                        /* phase -> Attack */
1010
                                                   SLOT->volume = 511; //Alone Coder
1011
                                                        SLOT->state = EG_ATT;
1012
 
1013
                                                        swap_flag = (SLOT->ssg&0x02); /* bit 1 = alternate */
1014
                                                }
1015
                                        }
1016
                                }
1017
                        }
1018
                        else
1019
                        {
1020
                                if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d2r)-1) ) )
1021
                                {
1022
                                        SLOT->volume += eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
1023
 
1024
                                        if ( SLOT->volume >= MAX_ATT_INDEX )
1025
                                        {
1026
                                                SLOT->volume = MAX_ATT_INDEX;
1027
                                                /* do not change SLOT->state (verified on real chip) */
1028
                                        }
1029
                                }
1030
 
1031
                        }
1032
                break;
1033
 
1034
                case EG_REL:    /* release phase */
1035
                                if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_rr)-1) ) )
1036
                                {
1037
                                        SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)];
1038
 
1039
                                        if ( SLOT->volume >= MAX_ATT_INDEX )
1040
                                        {
1041
                                                SLOT->volume = MAX_ATT_INDEX;
1042
                                                SLOT->state = EG_OFF;
1043
                                        }
1044
                                }
1045
                break;
1046
 
1047
                }
1048
 
1049
                out = SLOT->tl + ((UINT32)SLOT->volume);
1050
 
1051
                if ((SLOT->ssg&0x08) && (SLOT->ssgn&2) && (SLOT->state != EG_OFF/*Alone Coder*/))       /* negate output (changes come from alternate bit, init comes from attack bit) */
1052
                        out ^= 511/*Alone Coder*/; //((1<<ENV_BITS)-1); /* 1023 */
1053
 
1054
                /* we need to store the result here because we are going to change ssgn
1055
            in next instruction */
1056
                SLOT->vol_out = out;
1057
 
1058
                SLOT->ssgn ^= swap_flag;
1059
 
1060
                SLOT++;
1061
                i--;
1062
        }while (i);
1063
 
1064
}
1065
 
1066
enum { SS_INT8, SS_UINT8, SS_INT16, SS_UINT16, SS_INT32, SS_UINT32, SS_INT, SS_DOUBLE, SS_FLOAT};
1067
 
1068
void ss_register_entry(const char *module, int instance, const char *name, int type, void *data, unsigned int size)
1069
{
1070
        int i;
1071
        FILE* logfile=fopen("logfile.log", "a+");
1072
        if(!logfile)
1073
                return;
1074
 
1075
        fprintf(logfile,"%20s:%3d [%10s]: ",module,instance,name);
1076
 
1077
        if (type==SS_INT8) { fprintf(logfile,"INT8   "); for (i=0;i<(int)size;i++) fprintf(logfile,"[%2x]#%+02x ",i,((signed char*)data)[i]); }
1078
        if (type==SS_INT16) { fprintf(logfile,"INT16  "); for (i=0;i<(int)size;i++) fprintf(logfile,"[%2x]#%+04x ",i,((signed short*)data)[i]); }
1079
        if (type==SS_INT32) { fprintf(logfile,"INT32  "); for (i=0;i<(int)size;i++) fprintf(logfile,"[%2x]#%+08x ",i,((signed int*)data)[i]); }
1080
        if (type==SS_UINT8&&size==256) {
1081
                fprintf(logfile,"UINT8  ");
1082
                for (i=0;i<(int)size;i++) {
1083
                        if (i%16==0) fprintf(logfile,"\n");
1084
                        fprintf(logfile,"[%02x]#%02x ",i,((unsigned char*)data)[i]);
1085
                }
1086
        }
1087
        else if (type==SS_UINT8) { fprintf(logfile,"UINT8  "); for (i=0;i<(int)size;i++) fprintf(logfile,"[%2x]#%02x ",i,((unsigned char*)data)[i]); }
1088
        if (type==SS_UINT16) { fprintf(logfile,"UINT16 "); for (i=0;i<(int)size;i++) fprintf(logfile,"[%2x]#%04x ",i,((unsigned short*)data)[i]); }
1089
        if (type==SS_UINT32) { fprintf(logfile,"UINT32 "); for (i=0;i<(int)size;i++) fprintf(logfile,"[%2x]#%08x ",i,((unsigned int*)data)[i]); }
1090
 
1091
        if (type==SS_INT) { fprintf(logfile,"INT    "); fprintf(logfile,"    %d ",((int*)data)[0]); }
1092
        if (type==SS_DOUBLE) { fprintf(logfile,"DOUBLE "); for (i=0;i<(int)size;i++) fprintf(logfile,"[%d]%f ",i,((double*)data)[i]); }
1093
        if (type==SS_FLOAT) { fprintf(logfile,"FLOAT  "); for (i=0;i<(int)size;i++) fprintf(logfile,"[%d]%f ",i,((float*)data)[i]); }
1094
 
1095
        fprintf(logfile,"\n");
1096
 
1097
        fclose(logfile);
1098
        return;
1099
}
1100
 
1101
void state_save_register_UINT8 (const char *module, int instance, const char *name, UINT8 *val, unsigned size)
1102
{ ss_register_entry(module, instance, name, SS_UINT8, val, size); }
1103
 
1104
void state_save_register_INT8  (const char *module, int instance, const char *name, INT8 *val, unsigned size)
1105
{ ss_register_entry(module, instance, name, SS_INT8, val, size); }
1106
 
1107
void state_save_register_UINT16(const char *module, int instance, const char *name, UINT16 *val, unsigned size)
1108
{ ss_register_entry(module, instance, name, SS_UINT16, val, size); }
1109
 
1110
void state_save_register_INT16 (const char *module, int instance, const char *name, INT16 *val, unsigned size)
1111
{ ss_register_entry(module, instance, name, SS_INT16, val, size); }
1112
 
1113
void state_save_register_UINT32(const char *module, int instance, const char *name, UINT32 *val, unsigned size)
1114
{ ss_register_entry(module, instance, name, SS_UINT32, val, size); }
1115
 
1116
void state_save_register_INT32 (const char *module, int instance, const char *name, INT32 *val, unsigned size)
1117
{ ss_register_entry(module, instance, name, SS_INT32, val, size); }
1118
 
1119
void state_save_register_int   (const char *module, int instance, const char *name, int *val)
1120
{ ss_register_entry(module, instance, name, SS_INT, val, 1); }
1121
 
1122
void state_save_register_double(const char *module, int instance, const char *name, double *val, unsigned size)
1123
{ ss_register_entry(module, instance, name, SS_DOUBLE, val, size); }
1124
 
1125
void state_save_register_float(const char *module, int instance, const char *name, float *val, unsigned size)
1126
{ ss_register_entry(module, instance, name, SS_FLOAT, val, size); }
1127
 
1128
 
1129
/* FM channel save , internal state only */
1130
static void FMsave_state_channel(const char *name,int num,FM_CH *CH,int num_ch)
1131
{
1132
        int slot , ch;
1133
        char state_name[20];
1134
        const char slot_array[4] = { 1 , 3 , 2 , 4 };
1135
 
1136
        for(ch=0;ch<num_ch;ch++,CH++)
1137
        {
1138
                /* channel */
1139
                sprintf(state_name,"%s.CH%d",name,ch);
1140
                state_save_register_INT32(state_name, num, "feedback" , CH->op1_out , 2);
1141
                state_save_register_UINT32(state_name, num, "phasestep"   , &CH->fc , 1);
1142
                state_save_register_UINT32(state_name, num, "block_fnum"   , &CH->block_fnum , 1);
1143
                /* slots */
1144
                for(slot=0;slot<4;slot++)
1145
                {
1146
                        FM_SLOT *SLOT = &CH->SLOT[slot];
1147
 
1148
                        sprintf(state_name,"%s.CH%d.SLOT%d",name,ch,slot_array[slot]);
1149
                        state_save_register_UINT32(state_name, num, "phasecount" , &SLOT->phase, 1);
1150
                        state_save_register_UINT8 (state_name, num, "state"      , &SLOT->state, 1);
1151
                        state_save_register_INT32 (state_name, num, "volume"     , &SLOT->volume, 1);
1152
                }
1153
        }
1154
}
1155
 
1156
static void FMsave_state_st(const char *state_name,int num,FM_ST *ST)
1157
{
1158
#if FM_BUSY_FLAG_SUPPORT
1159
        state_save_register_double(state_name, num, "BusyExpire", &ST->BusyExpire , 1);
1160
#endif
1161
        state_save_register_UINT8 (state_name, num, "address"   , &ST->address , 1);
1162
        state_save_register_UINT8 (state_name, num, "IRQ"       , &ST->irq     , 1);
1163
        state_save_register_UINT8 (state_name, num, "IRQ MASK"  , &ST->irqmask , 1);
1164
        state_save_register_UINT8 (state_name, num, "status"    , &ST->status  , 1);
1165
        state_save_register_UINT32(state_name, num, "mode"      , &ST->mode    , 1);
1166
        state_save_register_UINT8 (state_name, num, "prescaler" , &ST->prescaler_sel , 1);
1167
        state_save_register_UINT8 (state_name, num, "freq latch", &ST->fn_h , 1);
1168
        state_save_register_int   (state_name, num, "TIMER A"   , &ST->TA   );
1169
        state_save_register_int   (state_name, num, "TIMER Acnt", &ST->TAC  );
1170
        state_save_register_UINT8 (state_name, num, "TIMER B"   , &ST->TB   , 1);
1171
        state_save_register_int   (state_name, num, "TIMER Bcnt", &ST->TBC  );
1172
 
1173
        state_save_register_int  (state_name, num, "clock"     , &ST->clock );
1174
        state_save_register_int  (state_name, num, "rate"      , &ST->rate );
1175
}
1176
 
1177
 
1178
/* prescaler set (and make time tables) */
1179
static void OPNSetPres(FM_OPN *OPN , int pres , int TimerPres, int SSGpres)
1180
{
1181
        int i;
1182
 
1183
        /* frequency base */
1184
        OPN->ST.freqbase = (OPN->ST.rate) ? ((double)OPN->ST.clock / OPN->ST.rate) / pres : 0;
1185
 
1186
#if 0
1187
        OPN->ST.rate = (double)OPN->ST.clock / pres;
1188
        OPN->ST.freqbase = 1.0;
1189
#endif
1190
 
1191
        OPN->eg_timer_add  = (UINT32)((1<<EG_SH)  *  OPN->ST.freqbase);
1192
        OPN->eg_timer_overflow = (UINT32)(( 3 ) * (1<<EG_SH));
1193
 
1194
        /* Timer base time */
1195
        OPN->ST.TimerBase = 1.0/((double)OPN->ST.clock / (double)TimerPres);
1196
 
1197
        /* SSG part  prescaler set */
1198
//      if( SSGpres ) (*OPN->ST.SSG->set_clock)( OPN->ST.param, OPN->ST.clock * 2 / SSGpres );
1199
        OPN->ST.SSGclock = OPN->ST.clock * 2 / SSGpres;
1200
 
1201
        /* make time tables */
1202
        init_timetables( &OPN->ST, dt_tab );
1203
 
1204
        /* there are 2048 FNUMs that can be generated using FNUM/BLK registers*/
1205
        /* calculate fnumber -> increment counter table */
1206
        for(i = 0; i < 2048; i++)
1207
        {
1208
                /* freq table for octave 7 */
1209
                /* OPN phase increment counter = 20bit */
1210
                OPN->fn_table[i] = (UINT32)( (double)i * 64 * OPN->ST.freqbase * (1<<(FREQ_SH-10)) );
1211
                /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
1212
        }
1213
 
1214
}
1215
 
1216
/* write a OPN mode register 0x20-0x2f */
1217
static void OPNWriteMode(FM_OPN *OPN, int r, int v)
1218
{
1219
        UINT8 c;
1220
        FM_CH *CH;
1221
 
1222
        switch(r){
1223
        case 0x21:      /* Test */
1224
                break;
1225
        case 0x22:      /* LFO FREQ (YM2608/YM2610/YM2610B/YM2612) */
1226
                break;
1227
        case 0x24:      /* timer A High 8*/
1228
                OPN->ST.TA = (OPN->ST.TA & 0x03)|(((int)v)<<2);
1229
                break;
1230
        case 0x25:      /* timer A Low 2*/
1231
                OPN->ST.TA = (OPN->ST.TA & 0x3fc)|(v&3);
1232
                break;
1233
        case 0x26:      /* timer B */
1234
                OPN->ST.TB = v;
1235
                break;
1236
        case 0x27:      /* mode, timer control */
1237
                set_timers( &(OPN->ST),OPN->ST.param,v );
1238
                break;
1239
        case 0x28:      /* key on / off */
1240
                c = v & 0x03;
1241
                if( c == 3 ) break;
1242
                CH = OPN->P_CH;
1243
                CH = &CH[c];
1244
                if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
1245
                if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
1246
                if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
1247
                if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
1248
                break;
1249
        }
1250
}
1251
 
1252
/* write a OPN register (0x30-0xff) */
1253
static void OPNWriteReg(FM_OPN *OPN, int r, int v)
1254
{
1255
        FM_CH *CH;
1256
        FM_SLOT *SLOT;
1257
 
1258
        UINT8 c = OPN_CHAN(r);
1259
 
1260
        if (c == 3) return; /* 0xX3,0xX7,0xXB,0xXF */
1261
 
1262
        CH = OPN->P_CH;
1263
        CH = &CH[c];
1264
 
1265
        SLOT = &(CH->SLOT[OPN_SLOT(r)]);
1266
 
1267
        switch( r & 0xf0 ) {
1268
        case 0x30:      /* DET , MUL */
1269
                set_det_mul(&OPN->ST,CH,SLOT,v);
1270
                break;
1271
 
1272
        case 0x40:      /* TL */
1273
                set_tl(CH,SLOT,v);
1274
                break;
1275
 
1276
        case 0x50:      /* KS, AR */
1277
                set_ar_ksr(CH,SLOT,v);
1278
                break;
1279
 
1280
        case 0x60:      /*     DR */
1281
                set_dr(SLOT,v);
1282
                break;
1283
 
1284
        case 0x70:      /*     SR */
1285
                set_sr(SLOT,v);
1286
                break;
1287
 
1288
        case 0x80:      /* SL, RR */
1289
                set_sl_rr(SLOT,v);
1290
                break;
1291
 
1292
        case 0x90:      /* SSG-EG */
1293
 
1294
                SLOT->ssg  =  v&0x0f;
1295
                SLOT->ssgn = (v&0x04)>>1; /* bit 1 in ssgn = attack */
1296
 
1297
                /* SSG-EG envelope shapes :
1298
 
1299
        E AtAlH
1300
        1 0 0 0  \\\\
1301
 
1302
        1 0 0 1  \___
1303
 
1304
        1 0 1 0  \/\/
1305
                  ___
1306
        1 0 1 1  \
1307
 
1308
        1 1 0 0  ////
1309
                  ___
1310
        1 1 0 1  /
1311
 
1312
        1 1 1 0  /\/\
1313
 
1314
        1 1 1 1  /___
1315
 
1316
 
1317
        E = SSG-EG enable
1318
 
1319
        The shapes are generated using Attack, Decay and Sustain phases.
1320
 
1321
        Each single character in the diagrams above represents this whole
1322
        sequence:
1323
 
1324
        - when KEY-ON = 1, normal Attack phase is generated (*without* any
1325
          difference when compared to normal mode),
1326
 
1327
        - later, when envelope level reaches minimum level (max volume),
1328
          the EG switches to Decay phase (which works with bigger steps
1329
          when compared to normal mode - see below),
1330
 
1331
        - later when envelope level passes the SL level,
1332
          the EG switches to Sustain phase (which works with bigger steps
1333
          when compared to normal mode - see below),
1334
 
1335
        - finally when envelope level reaches maximum level (min volume),
1336
          the EG switches to Attack phase again (depends on actual waveform).
1337
 
1338
        Important is that when switch to Attack phase occurs, the phase counter
1339
        of that operator will be zeroed-out (as in normal KEY-ON) but not always.
1340
        (I havent found the rule for that - perhaps only when the output level is low)
1341
 
1342
        The difference (when compared to normal Envelope Generator mode) is
1343
        that the resolution in Decay and Sustain phases is 4 times lower;
1344
        this results in only 256 steps instead of normal 1024.
1345
        In other words:
1346
        when SSG-EG is disabled, the step inside of the EG is one,
1347
        when SSG-EG is enabled, the step is four (in Decay and Sustain phases).
1348
 
1349
        Times between the level changes are the same in both modes.
1350
 
1351
 
1352
        Important:
1353
        Decay 1 Level (so called SL) is compared to actual SSG-EG output, so
1354
        it is the same in both SSG and no-SSG modes, with this exception:
1355
 
1356
        when the SSG-EG is enabled and is generating raising levels
1357
        (when the EG output is inverted) the SL will be found at wrong level !!!
1358
        For example, when SL=02:
1359
 
1360
            96-6 = -90dB in inverted EG output
1361
        Which means that EG compares its level to SL as usual, and that the
1362
        output is simply inverted afterall.
1363
 
1364
 
1365
        The Yamaha's manuals say that AR should be set to 0x1f (max speed).
1366
        That is not necessary, but then EG will be generating Attack phase.
1367
 
1368
        */
1369
 
1370
 
1371
                break;
1372
 
1373
        case 0xa0:
1374
                switch( OPN_SLOT(r) ){
1375
                case 0:         /* 0xa0-0xa2 : FNUM1 */
1376
                        {
1377
                                UINT32 fn = (((UINT32)( (OPN->ST.fn_h)&7))<<8) + v;
1378
                                UINT8 blk = OPN->ST.fn_h>>3;
1379
                                /* keyscale code */
1380
                                CH->kcode = (blk<<2) | opn_fktable[fn >> 7];
1381
                                /* phase increment counter */
1382
                                CH->fc = OPN->fn_table[fn]>>(7-blk);
1383
 
1384
                                /* store fnum in clear form for LFO PM calculations */
1385
                                CH->block_fnum = (blk<<11) | fn;
1386
 
1387
                                CH->SLOT[SLOT1].Incr=-1;
1388
                        }
1389
                        break;
1390
                case 1:         /* 0xa4-0xa6 : FNUM2,BLK */
1391
                        OPN->ST.fn_h = v&0x3f;
1392
                        break;
1393
                case 2:         /* 0xa8-0xaa : 3CH FNUM1 */
1394
                        if(r < 0x100)
1395
                        {
1396
                                UINT32 fn = (((UINT32)(OPN->SL3.fn_h&7))<<8) + v;
1397
                                UINT8 blk = OPN->SL3.fn_h>>3;
1398
                                /* keyscale code */
1399
                                OPN->SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];
1400
                                /* phase increment counter */
1401
                                OPN->SL3.fc[c] = OPN->fn_table[fn]>>(7-blk);
1402
                                OPN->SL3.block_fnum[c] = fn;
1403
                                (OPN->P_CH)[2].SLOT[SLOT1].Incr=-1;
1404
                        }
1405
                        break;
1406
                case 3:         /* 0xac-0xae : 3CH FNUM2,BLK */
1407
                        if(r < 0x100)
1408
                                OPN->SL3.fn_h = v&0x3f;
1409
                        break;
1410
                }
1411
                break;
1412
 
1413
        case 0xb0:
1414
                switch( OPN_SLOT(r) ){
1415
                case 0:         /* 0xb0-0xb2 : FB,ALGO */
1416
                        {
1417
                                int feedback = (v>>3)&7;
1418
                                CH->ALGO = v&7;
1419
                                CH->FB   = feedback ? feedback+6 : 0;
1420
                                setup_connection( CH, c );
1421
                        }
1422
                        break;
1423
                }
1424
                break;
1425
        }
1426
}
1427
 
1428
 
1429
/*
1430
  prescaler circuit (best guess to verified chip behaviour)
1431
 
1432
               +--------------+  +-sel2-+
1433
               |              +--|in20  |
1434
         +---+ |  +-sel1-+       |      |
1435
M-CLK -+-|1/2|-+--|in10  | +---+ |   out|--INT_CLOCK
1436
       | +---+    |   out|-|1/3|-|in21  |
1437
       +----------|in11  | +---+ +------+
1438
                  +------+
1439
 
1440
reg.2d : sel2 = in21 (select sel2)
1441
reg.2e : sel1 = in11 (select sel1)
1442
reg.2f : sel1 = in10 , sel2 = in20 (clear selector)
1443
reset  : sel1 = in11 , sel2 = in21 (clear both)
1444
 
1445
*/
1446
void OPNPrescaler_w(FM_OPN *OPN , int addr, int pre_divider)
1447
{
1448
        static const int opn_pres[4] = { 2*12 , 2*12 , 6*12 , 3*12 };
1449
        static const int ssg_pres[4] = {    1 ,    1 ,    4 ,    2 };
1450
        int sel;
1451
 
1452
        switch(addr)
1453
        {
1454
        case 0:         /* when reset */
1455
                OPN->ST.prescaler_sel = 2;
1456
                break;
1457
        case 1:         /* when postload */
1458
                break;
1459
        case 0x2d:      /* divider sel : select 1/1 for 1/3line    */
1460
                OPN->ST.prescaler_sel |= 0x02;
1461
                break;
1462
        case 0x2e:      /* divider sel , select 1/3line for output */
1463
                OPN->ST.prescaler_sel |= 0x01;
1464
                break;
1465
        case 0x2f:      /* divider sel , clear both selector to 1/2,1/2 */
1466
                OPN->ST.prescaler_sel = 0;
1467
                break;
1468
        }
1469
        sel = OPN->ST.prescaler_sel & 3;
1470
        /* update prescaler */
1471
        OPNSetPres( OPN,        opn_pres[sel]*pre_divider,
1472
                                                opn_pres[sel]*pre_divider,
1473
                                                ssg_pres[sel]*pre_divider );
1474
}
1475
 
1476
/*****************************************************************************/
1477
/*      YM2203 local section                                                 */
1478
/*****************************************************************************/
1479
 
1480
/* Generate samples for one of the YM2203s */
1481
void YM2203UpdateOne(void *chip, FMSAMPLE *buffer, int length)
1482
{
1483
        YM2203 *F2203 = (YM2203 *)chip;
1484
        FM_OPN *OPN =   &F2203->OPN;
1485
        int i;
1486
        FMSAMPLE *buf = buffer;
1487
 
1488
        _cur_chip = (void *)F2203;
1489
        _State    = &F2203->OPN.ST;
1490
        _cch[0]   = &F2203->CH[0];
1491
        _cch[1]   = &F2203->CH[1];
1492
        _cch[2]   = &F2203->CH[2];
1493
 
1494
        /* refresh PG and EG */
1495
        refresh_fc_eg_chan( _cch[0] );
1496
        refresh_fc_eg_chan( _cch[1] );
1497
        if( ((_State->mode & 0xc0) == 0x40) )
1498
        {
1499
                // 3SLOT MODE
1500
                if( _cch[2]->SLOT[SLOT1].Incr==-1)
1501
                {
1502
                        refresh_fc_eg_slot(&_cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
1503
                        refresh_fc_eg_slot(&_cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
1504
                        refresh_fc_eg_slot(&_cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
1505
                        refresh_fc_eg_slot(&_cch[2]->SLOT[SLOT4] , _cch[2]->fc , _cch[2]->kcode );
1506
                }
1507
        }else
1508
        refresh_fc_eg_chan( _cch[2] );
1509
 
1510
 
1511
        /* buffering */
1512
        for (i=0; i < length ; i++)
1513
        {
1514
                /* clear outputs */
1515
                _out_fm[0] = 0;
1516
                _out_fm[1] = 0;
1517
                _out_fm[2] = 0;
1518
 
1519
                /* advance envelope generator */
1520
                OPN->eg_timer += OPN->eg_timer_add;
1521
                while (OPN->eg_timer >= OPN->eg_timer_overflow)
1522
                {
1523
                        OPN->eg_timer -= OPN->eg_timer_overflow;
1524
                        OPN->eg_cnt++;
1525
 
1526
                        advance_eg_channel(OPN, &_cch[0]->SLOT[SLOT1]);
1527
                        advance_eg_channel(OPN, &_cch[1]->SLOT[SLOT1]);
1528
                        advance_eg_channel(OPN, &_cch[2]->SLOT[SLOT1]);
1529
                }
1530
 
1531
                /* calculate FM */
1532
                chan_calc(OPN, _cch[0] );
1533
                chan_calc(OPN, _cch[1] );
1534
                chan_calc(OPN, _cch[2] );
1535
 
1536
                /* buffering */
1537
                {
1538
                        int lt;
1539
                        lt = _out_fm[0] + _out_fm[1] + _out_fm[2];
1540
                        lt >>= FINAL_SH;
1541
                        Limit( lt , MAXOUT, MINOUT );
1542
//                      #ifdef SAVE_SAMPLE
1543
//                              SAVE_ALL_CHANNELS
1544
//                      #endif
1545
 
1546
                        /* buffering */
1547
                        buf[i] = lt;
1548
                }
1549
 
1550
                /* timer A control */
1551
                INTERNAL_TIMER_A( _State , _cch[2] )
1552
        }
1553
        INTERNAL_TIMER_B(_State,length)
1554
}
1555
 
1556
/* ---------- reset one of chip ---------- */
1557
void YM2203ResetChip(void *chip)
1558
{
1559
        int i;
1560
        YM2203 *F2203 = (YM2203 *)chip;
1561
        FM_OPN *OPN = &F2203->OPN;
1562
 
1563
        /* Reset Prescaler */
1564
        OPNPrescaler_w(OPN, 0 , 1 );
1565
        /* reset SSG section */
1566
//      (*OPN->ST.SSG->reset)(OPN->ST.param);
1567
        /* status clear */
1568
        FM_IRQMASK_SET(&OPN->ST,0x03);
1569
        FM_BUSY_CLEAR(&OPN->ST);
1570
        OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
1571
 
1572
        OPN->eg_timer = 0;
1573
        OPN->eg_cnt   = 0;
1574
 
1575
        FM_STATUS_RESET(&OPN->ST, 0xff);
1576
 
1577
        reset_channels( &OPN->ST , F2203->CH , 3 );
1578
        /* reset OPerator paramater */
1579
        for(i = 0xb2 ; i >= 0x30 ; i-- ) OPNWriteReg(OPN,i,0);
1580
        for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
1581
}
1582
 
1583
//#ifdef _STATE_H
1584
void YM2203Postload(void *chip)
1585
{
1586
        if (chip)
1587
        {
1588
                YM2203 *F2203 = (YM2203 *)chip;
1589
                int r;
1590
 
1591
                /* prescaler */
1592
                OPNPrescaler_w(&F2203->OPN,1,1);
1593
 
1594
                /* SSG registers */
1595
                for(r=0;r<16;r++)
1596
                {
1597
//                      (*F2203->OPN.ST.SSG->write)(F2203->OPN.ST.param,0,r);
1598
//                      (*F2203->OPN.ST.SSG->write)(F2203->OPN.ST.param,1,F2203->REGS[r]);
1599
                }
1600
 
1601
                /* OPN registers */
1602
                /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
1603
                for(r=0x30;r<0x9e;r++)
1604
                        if((r&3) != 3)
1605
                                OPNWriteReg(&F2203->OPN,r,F2203->REGS[r]);
1606
                /* FB / CONNECT , L / R / AMS / PMS */
1607
                for(r=0xb0;r<0xb6;r++)
1608
                        if((r&3) != 3)
1609
                                OPNWriteReg(&F2203->OPN,r,F2203->REGS[r]);
1610
 
1611
                /* channels */
1612
                /*FM_channel_postload(F2203->CH,3);*/
1613
        }
1614
        _cur_chip = NULL;
1615
}
1616
 
1617
void YM2203_save_state(void *chip, int index)
1618
{
1619
        if (chip)
1620
        {
1621
                YM2203 *F2203 = (YM2203 *)chip;
1622
                const char statename[] = "YM2203";
1623
 
1624
                state_save_register_UINT8 (statename, index, "regs"   , F2203->REGS   , 256);
1625
                FMsave_state_st(statename,index,&F2203->OPN.ST);
1626
                FMsave_state_channel(statename,index,F2203->CH,3);
1627
                /* 3slots */
1628
                state_save_register_UINT32 (statename, index, "slot3fc" , F2203->OPN.SL3.fc , 3);
1629
                state_save_register_UINT8  (statename, index, "slot3fh" , &F2203->OPN.SL3.fn_h , 1);
1630
                state_save_register_UINT8  (statename, index, "slot3kc" , F2203->OPN.SL3.kcode , 3);
1631
        }
1632
}
1633
//#endif /* _STATE_H */
1634
 
1635
/* ----------  Initialize YM2203 emulator(s) ----------
1636
   'num' is the number of virtual YM2203s to allocate
1637
   'clock' is the chip clock in Hz
1638
   'rate' is sampling rate
1639
*/
1640
void * YM2203Init(void *param, int index, int clock, int rate
1641
//                              ,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler,
1642
//               const struct ssg_callbacks *ssg
1643
               )
1644
{
1645
        YM2203 *F2203;
1646
 
1647
        _cur_chip = NULL;       /* hiro-shi!! */
1648
 
1649
        /* allocate ym2203 state space */
1650
        if( (F2203 = (YM2203 *)malloc(sizeof(YM2203)))==NULL)
1651
                return NULL;
1652
        /* clear */
1653
        memset(F2203,0,sizeof(YM2203));
1654
 
1655
        if( !init_tables() )
1656
        {
1657
                free( F2203 );
1658
                return NULL;
1659
        }
1660
 
1661
        F2203->OPN.ST.param = param;
1662
        F2203->OPN.type = TYPE_YM2203;
1663
        F2203->OPN.P_CH = F2203->CH;
1664
        F2203->OPN.ST.clock = clock;
1665
        F2203->OPN.ST.rate = rate;
1666
 
1667
//      F2203->OPN.ST.Timer_Handler = TimerHandler;
1668
//      F2203->OPN.ST.IRQ_Handler   = IRQHandler;
1669
//      F2203->OPN.ST.SSG           = ssg;
1670
        YM2203ResetChip(F2203);
1671
 
1672
#ifdef _STATE_H
1673
        YM2203_save_state(F2203, index);
1674
#endif
1675
        return F2203;
1676
}
1677
 
1678
/* shut down emulator */
1679
void YM2203Shutdown(void *chip)
1680
{
1681
        YM2203 *FM2203 = (YM2203 *)chip;
1682
 
1683
        FMCloseTable();
1684
        free(FM2203);
1685
        chip=NULL;
1686
}
1687
 
1688
/* YM2203 I/O interface */
1689
int YM2203Write(void *chip,int a,UINT8 v)
1690
{
1691
        YM2203 *F2203 = (YM2203 *)chip;
1692
        FM_OPN *OPN = &F2203->OPN;
1693
 
1694
        if( !(a&1) )
1695
        {       // address port
1696
                OPN->ST.address = (v &= 0xff);
1697
 
1698
                // Write register to SSG emulator
1699
//              if( v < 16 ) (*OPN->ST.SSG->write)(OPN->ST.param,0,v);
1700
 
1701
        }
1702
        else
1703
        {       // data port
1704
                int addr = OPN->ST.address;
1705
                // prescaler select : 2d,2e,2f
1706
                if( addr >= 0x2d && addr <= 0x2f )
1707
                        OPNPrescaler_w(OPN , addr , 1);
1708
                else {
1709
//#ifdef _STATE_H
1710
                        F2203->REGS[addr] = v;
1711
//#endif
1712
                        switch( addr & 0xf0 )
1713
                        {
1714
                        case 0x00:      /* 0x00-0x0f : SSG section */
1715
                                /* Write data to SSG emulator */
1716
//                              (*OPN->ST.SSG->write)(OPN->ST.param,a,v);
1717
                                break;
1718
                        case 0x20:      /* 0x20-0x2f : Mode section */
1719
//                              YM2203UpdateReq(OPN->ST.param);
1720
                                /* write register */
1721
                                OPNWriteMode(OPN,addr,v);
1722
                                break;
1723
                        default:        /* 0x30-0xff : OPN section */
1724
//                              YM2203UpdateReq(OPN->ST.param);
1725
                                /* write register */
1726
                                OPNWriteReg(OPN,addr,v);
1727
                        }
1728
                        FM_BUSY_SET(&OPN->ST,1);
1729
                }
1730
        }
1731
        return OPN->ST.irq;
1732
}
1733
 
1734
UINT8 YM2203Read(void *chip,int a)
1735
{
1736
        YM2203 *F2203 = (YM2203 *)chip;
1737
        int addr = F2203->OPN.ST.address;
1738
        UINT8 ret = 0;
1739
 
1740
        if( !(a&1) )
1741
        {       /* status port */
1742
                ret = FM_STATUS_FLAG(&F2203->OPN.ST);
1743
        }
1744
        else
1745
        {       /* data port (only SSG) */
1746
//              if( addr < 16 ) ret = (*F2203->OPN.ST.SSG->read)(F2203->OPN.ST.param);
1747
        }
1748
        return ret;
1749
}
1750
 
1751
int YM2203TimerOver(void *chip,int c)
1752
{
1753
        YM2203 *F2203 = (YM2203 *)chip;
1754
 
1755
        if( c )
1756
        {       /* Timer B */
1757
                TimerBOver( &(F2203->OPN.ST) );
1758
        }
1759
        else
1760
        {       /* Timer A */
1761
//              YM2203UpdateReq(F2203->OPN.ST.param);
1762
                /* timer update */
1763
                TimerAOver( &(F2203->OPN.ST) );
1764
                /* CSM mode key,TL control */
1765
                if( F2203->OPN.ST.mode & 0x80 )
1766
                {       /* CSM mode auto key on */
1767
                        CSMKeyControll( &(F2203->CH[2]) );
1768
                }
1769
        }
1770
        return F2203->OPN.ST.irq;
1771
}