DGen/SDL
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Classes | Macros | Functions | Variables
fm.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include "fm.h"

Classes

struct  FM_SLOT
struct  FM_CH
struct  FM_ST
struct  FM_3SLOT
struct  FM_OPN
struct  YM2612

Macros

#define YM2610B_WARNING
#define PI   3.14159265358979323846
#define BUILD_OPN   (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B||BUILD_YM2612)
#define BUILD_OPN_PRESCALER   (BUILD_YM2203||BUILD_YM2608)
#define TYPE_SSG   0x01 /* SSG support */
#define TYPE_LFOPAN   0x02 /* OPN type LFO and PAN */
#define TYPE_6CH   0x04 /* FM 6CH / 3CH */
#define TYPE_DAC   0x08 /* YM2612's DAC device */
#define TYPE_ADPCM   0x10 /* two ADPCM units */
#define TYPE_2610   0x20 /* bogus flag to differentiate 2608 from 2610 */
#define TYPE_YM2203   (TYPE_SSG)
#define TYPE_YM2608   (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
#define TYPE_YM2610   (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM |TYPE_2610)
#define TYPE_YM2612   (TYPE_DAC |TYPE_LFOPAN |TYPE_6CH)
#define FREQ_SH   16 /* 16.16 fixed point (frequency calculations) */
#define EG_SH   16 /* 16.16 fixed point (envelope generator timing) */
#define LFO_SH   24 /* 8.24 fixed point (LFO calculations) */
#define TIMER_SH   16 /* 16.16 fixed point (timers calculations) */
#define FREQ_MASK   ((1<<FREQ_SH)-1)
#define ENV_BITS   10
#define ENV_LEN   (1<<ENV_BITS)
#define ENV_STEP   (128.0/ENV_LEN)
#define MAX_ATT_INDEX   (ENV_LEN-1) /* 1023 */
#define MIN_ATT_INDEX   (0) /* 0 */
#define EG_ATT   4
#define EG_DEC   3
#define EG_SUS   2
#define EG_REL   1
#define EG_OFF   0
#define SIN_BITS   10
#define SIN_LEN   (1<<SIN_BITS)
#define SIN_MASK   (SIN_LEN-1)
#define TL_RES_LEN   (256) /* 8 bits addressing (real chip) */
#define FINAL_SH   (0)
#define MAXOUT   (+32767)
#define MINOUT   (-32768)
#define TL_TAB_LEN   (13*2*TL_RES_LEN)
#define ENV_QUIET   (TL_TAB_LEN>>3)
#define SC(db)   (UINT32) ( db * (4.0/ENV_STEP) )
#define RATE_STEPS   (8)
#define O(a)   (a*RATE_STEPS)
#define O(a)   (a*1)
#define OPN_CHAN(N)   (N&3)
#define OPN_SLOT(N)   ((N>>2)&3)
#define SLOT1   0
#define SLOT2   2
#define SLOT3   1
#define SLOT4   3
#define OUTD_RIGHT   1
#define OUTD_LEFT   2
#define OUTD_CENTER   3
#define LOG_ERR   3 /* ERROR */
#define LOG_WAR   2 /* WARNING */
#define LOG_INF   1 /* INFORMATION */
#define LOG_LEVEL   LOG_INF
#define LOG(n, x)   (void)0
#define Limit(val, max, min)
#define INTERNAL_TIMER_A(type, ST, CSM_CH)
#define INTERNAL_TIMER_B(ST, step)
#define FM_STATUS_FLAG(ST)   ((ST)->status)
#define FM_BUSY_SET(ST, bclock)   {}
#define FM_BUSY_CLEAR(ST)   {}
#define volume_calc(OP)   ((OP)->vol_out + (AM & (OP)->AMmask))
#define YMREG_LFO   0x22
#define YMREG_TIMER_A1   0x24
#define YMREG_TIMER_A2   0x25
#define YMREG_TIMER_B   0x26
#define YMREG_CH3_TIMERS   0x27
#define YMREG_KEY   0x28
#define YMREG_DAC   0x2a
#define YMREG_DAC_ENABLE   0x2b
#define YMREG_OP_SSG_EG   0x90
#define YMREG_CHAN_FREQ1   0xa0
#define YMREG_CHAN_FREQ2   0xa4
#define YMREG_CHAN_CH3_OP1_FREQ1   0xa2
#define YMREG_CHAN_CH3_OP1_FREQ2   0xa6
#define YMREG_CHAN_CH3_OP2_FREQ1   0xa8
#define YMREG_CHAN_CH3_OP2_FREQ2   0xac
#define YMREG_CHAN_CH3_OP3_FREQ1   0xa9
#define YMREG_CHAN_CH3_OP3_FREQ2   0xad
#define YMREG_CHAN_CH3_OP4_FREQ1   0xaa
#define YMREG_CHAN_CH3_OP4_FREQ2   0xae
#define YMREG_CHAN_FBACK_ALGO   0xb0
#define YMREG_CHAN_LR_AMS_FMS   0xb4
#define YMREG_OP_DT1_MUL   0x30
#define YMREG_OP_TL   0x40
#define YMREG_OP_RS_AR   0x50
#define YMREG_OP_AM_D1R   0x60
#define YMREG_OP_D2R   0x70
#define YMREG_OP_D1L_RR   0x80
#define YMREG_OP_SSG_EG   0x90
#define DEBUG_PRINT_GLOBAL_VAL(r, v)   printf(" %-15s: 0x%02x\n", r, v);
#define DEBUG_PRINT_OP_VAL(r, v)   printf(" %-15s: 0x%02x\n", r, v);
#define DEBUG_MAX_OPS   4
#define DEBUG_PRINT_CHAN_VAL(r, v)   printf(" %-15s: 0x%02x\n", r, v);
#define DEBUG_MAX_CHAN   6

Functions

INLINE void FM_STATUS_SET (FM_ST *ST, int flag)
INLINE void FM_STATUS_RESET (FM_ST *ST, int flag)
INLINE void FM_IRQMASK_SET (FM_ST *ST, int flag)
INLINE void set_timers (FM_ST *ST, int n, int v)
INLINE void TimerAOver (FM_ST *ST)
INLINE void TimerBOver (FM_ST *ST)
INLINE void FM_KEYON (UINT8 type, FM_CH *CH, int s)
INLINE void FM_KEYOFF (FM_CH *CH, int s)
static void setup_connection (FM_CH *CH, int ch)
INLINE void set_det_mul (FM_ST *ST, FM_CH *CH, FM_SLOT *SLOT, int v)
INLINE void set_tl (FM_CH *CH, FM_SLOT *SLOT, int v)
INLINE void set_ar_ksr (UINT8 type, FM_CH *CH, FM_SLOT *SLOT, int v)
INLINE void set_dr (UINT8 type, FM_SLOT *SLOT, int v)
INLINE void set_sr (UINT8 type, FM_SLOT *SLOT, int v)
INLINE void set_sl_rr (UINT8 type, FM_SLOT *SLOT, int v)
INLINE signed int op_calc (UINT32 phase, unsigned int env, signed int pm)
INLINE signed int op_calc1 (UINT32 phase, unsigned int env, signed int pm)
INLINE void advance_lfo (FM_OPN *OPN)
INLINE void advance_eg_channel (FM_OPN *OPN, FM_SLOT *SLOT)
INLINE void update_phase_lfo_slot (FM_OPN *OPN, FM_SLOT *SLOT, INT32 pms, UINT32 block_fnum)
INLINE void update_phase_lfo_channel (FM_OPN *OPN, FM_CH *CH)
INLINE void chan_calc (FM_OPN *OPN, FM_CH *CH, int chnum)
INLINE void refresh_fc_eg_slot (FM_OPN *OPN, FM_SLOT *SLOT, int fc, int kc)
static void refresh_fc_eg_chan (FM_OPN *OPN, FM_CH *CH)
static void init_timetables (FM_ST *ST, const UINT8 *dttable)
static void reset_channels (FM_ST *ST, FM_CH *CH, int num)
static int init_tables (void)
static void FMCloseTable (void)
INLINE void CSMKeyControll (UINT8 type, FM_CH *CH)
static void OPNSetPres (FM_OPN *OPN, int pres, int TimerPres, int SSGpres)
static void OPNWriteMode (FM_OPN *OPN, int r, int v)
static void OPNWriteReg (FM_OPN *OPN, int r, int v)
void YM2612UpdateOne (int num, INT16 *buffer, unsigned int length, unsigned int volume, int loud)
int YM2612Init (int num, int clock, int rate, int mjazz, FM_TIMERHANDLER TimerHandler, FM_IRQHANDLER IRQHandler)
void YM2612Shutdown ()
void YM2612ResetChip (int num)
int YM2612Write (int n, int a, UINT8 v)
UINT8 YM2612Read (int n, int a)
int YM2612TimerOver (int n, int c)
void YM2612_dump (int num, uint8_t buf[512])
void YM2612_restore (int num, uint8_t buf[512])
void debug_get_chan_part_and_offset (uint8_t chan, uint8_t *part, uint8_t *offs)
void debug_show_ym2612_global_regs (uint8_t regs[512])
uint8_t debug_get_opn_reg_addr (uint8_t reg, uint8_t ch, uint8_t op)
void debug_show_ym2612_operator_regs (uint8_t regs[512], uint8_t ch, uint8_t op)
uint8_t debug_get_chan_reg_addr (uint8_t reg, uint8_t ch)
void debug_show_ym2612_chan_regs (uint8_t regs[512], uint8_t ch)
void debug_show_ym2612_regs ()

Variables

static signed int tl_tab [TL_TAB_LEN]
static unsigned int sin_tab [SIN_LEN]
static const UINT32 sl_table [16]
static const UINT8 eg_inc [19 *RATE_STEPS]
static const UINT8 eg_rate_select [32+64+32]
static const UINT8 eg_rate_select2612 [32+64+32]
static const UINT8 eg_rate_shift [32+64+32]
static const UINT8 dt_tab [4 *32]
static const UINT8 opn_fktable [16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3}
static const UINT32 lfo_samples_per_step [8] = {108, 77, 71, 67, 62, 44, 8, 5}
static const UINT8 lfo_ams_depth_shift [4] = {8, 3, 1, 0}
static const UINT8 lfo_pm_output [7 *8][8]
static INT32 lfo_pm_table [128 *8 *32]
static void * cur_chip = 0
static FM_STState
static FM_CHcch [8]
static INT32 m2
static INT32 c1
static INT32 c2
static INT32 mem
static INT32 out_fm [8]
static UINT32 LFO_AM
static INT32 LFO_PM
static int YM2612NumChips
static YM2612FM2612 = NULL
static int dacen

Macro Definition Documentation

#define BUILD_OPN_PRESCALER   (BUILD_YM2203||BUILD_YM2608)
#define DEBUG_MAX_CHAN   6
#define DEBUG_MAX_OPS   4
#define DEBUG_PRINT_CHAN_VAL (   r,
 
)    printf(" %-15s: 0x%02x\n", r, v);
#define DEBUG_PRINT_GLOBAL_VAL (   r,
 
)    printf(" %-15s: 0x%02x\n", r, v);
#define DEBUG_PRINT_OP_VAL (   r,
 
)    printf(" %-15s: 0x%02x\n", r, v);
#define EG_ATT   4
#define EG_DEC   3
#define EG_OFF   0
#define EG_REL   1
#define EG_SH   16 /* 16.16 fixed point (envelope generator timing) */
#define EG_SUS   2
#define ENV_BITS   10
#define ENV_LEN   (1<<ENV_BITS)
#define ENV_QUIET   (TL_TAB_LEN>>3)
#define ENV_STEP   (128.0/ENV_LEN)
#define FINAL_SH   (0)
#define FM_BUSY_CLEAR (   ST)    {}
#define FM_BUSY_SET (   ST,
  bclock 
)    {}
#define FM_STATUS_FLAG (   ST)    ((ST)->status)
#define FREQ_MASK   ((1<<FREQ_SH)-1)
#define FREQ_SH   16 /* 16.16 fixed point (frequency calculations) */
#define INTERNAL_TIMER_A (   type,
  ST,
  CSM_CH 
)
#define INTERNAL_TIMER_B (   ST,
  step 
)
#define LFO_SH   24 /* 8.24 fixed point (LFO calculations) */
#define Limit (   val,
  max,
  min 
)
Value:
{ \
if ( val > max ) val = max; \
else if ( val < min ) val = min; \
}
#define LOG (   n,
  x 
)    (void)0
#define LOG_ERR   3 /* ERROR */
#define LOG_INF   1 /* INFORMATION */
#define LOG_LEVEL   LOG_INF
#define LOG_WAR   2 /* WARNING */
#define MAX_ATT_INDEX   (ENV_LEN-1) /* 1023 */
#define MAXOUT   (+32767)
#define MIN_ATT_INDEX   (0) /* 0 */
#define MINOUT   (-32768)
#define O (   a)    (a*RATE_STEPS)
#define O (   a)    (a*1)
#define OPN_CHAN (   N)    (N&3)
#define OPN_SLOT (   N)    ((N>>2)&3)
#define OUTD_CENTER   3
#define OUTD_LEFT   2
#define OUTD_RIGHT   1
#define PI   3.14159265358979323846
#define RATE_STEPS   (8)
#define SC (   db)    (UINT32) ( db * (4.0/ENV_STEP) )
#define SIN_BITS   10
#define SIN_LEN   (1<<SIN_BITS)
#define SIN_MASK   (SIN_LEN-1)
#define SLOT1   0
#define SLOT2   2
#define SLOT3   1
#define SLOT4   3
#define TIMER_SH   16 /* 16.16 fixed point (timers calculations) */
#define TL_RES_LEN   (256) /* 8 bits addressing (real chip) */
#define TL_TAB_LEN   (13*2*TL_RES_LEN)
#define TYPE_2610   0x20 /* bogus flag to differentiate 2608 from 2610 */
#define TYPE_6CH   0x04 /* FM 6CH / 3CH */
#define TYPE_ADPCM   0x10 /* two ADPCM units */
#define TYPE_DAC   0x08 /* YM2612's DAC device */
#define TYPE_LFOPAN   0x02 /* OPN type LFO and PAN */
#define TYPE_SSG   0x01 /* SSG support */
#define TYPE_YM2203   (TYPE_SSG)
#define TYPE_YM2608   (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
#define TYPE_YM2610   (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM |TYPE_2610)
#define TYPE_YM2612   (TYPE_DAC |TYPE_LFOPAN |TYPE_6CH)
#define volume_calc (   OP)    ((OP)->vol_out + (AM & (OP)->AMmask))
#define YM2610B_WARNING
#define YMREG_CH3_TIMERS   0x27
#define YMREG_CHAN_CH3_OP1_FREQ1   0xa2
#define YMREG_CHAN_CH3_OP1_FREQ2   0xa6
#define YMREG_CHAN_CH3_OP2_FREQ1   0xa8
#define YMREG_CHAN_CH3_OP2_FREQ2   0xac
#define YMREG_CHAN_CH3_OP3_FREQ1   0xa9
#define YMREG_CHAN_CH3_OP3_FREQ2   0xad
#define YMREG_CHAN_CH3_OP4_FREQ1   0xaa
#define YMREG_CHAN_CH3_OP4_FREQ2   0xae
#define YMREG_CHAN_FBACK_ALGO   0xb0
#define YMREG_CHAN_FREQ1   0xa0
#define YMREG_CHAN_FREQ2   0xa4
#define YMREG_CHAN_LR_AMS_FMS   0xb4
#define YMREG_DAC   0x2a
#define YMREG_DAC_ENABLE   0x2b
#define YMREG_KEY   0x28
#define YMREG_LFO   0x22
#define YMREG_OP_AM_D1R   0x60
#define YMREG_OP_D1L_RR   0x80
#define YMREG_OP_D2R   0x70
#define YMREG_OP_DT1_MUL   0x30
#define YMREG_OP_RS_AR   0x50
#define YMREG_OP_SSG_EG   0x90
#define YMREG_OP_SSG_EG   0x90
#define YMREG_OP_TL   0x40
#define YMREG_TIMER_A1   0x24
#define YMREG_TIMER_A2   0x25
#define YMREG_TIMER_B   0x26

Function Documentation

INLINE void advance_eg_channel ( FM_OPN OPN,
FM_SLOT SLOT 
)
INLINE void advance_lfo ( FM_OPN OPN)
INLINE void chan_calc ( FM_OPN OPN,
FM_CH CH,
int  chnum 
)
INLINE void CSMKeyControll ( UINT8  type,
FM_CH CH 
)
void debug_get_chan_part_and_offset ( uint8_t  chan,
uint8_t *  part,
uint8_t *  offs 
)
uint8_t debug_get_chan_reg_addr ( uint8_t  reg,
uint8_t  ch 
)
uint8_t debug_get_opn_reg_addr ( uint8_t  reg,
uint8_t  ch,
uint8_t  op 
)
void debug_show_ym2612_chan_regs ( uint8_t  regs[512],
uint8_t  ch 
)
void debug_show_ym2612_global_regs ( uint8_t  regs[512])
void debug_show_ym2612_operator_regs ( uint8_t  regs[512],
uint8_t  ch,
uint8_t  op 
)
void debug_show_ym2612_regs ( void  )
INLINE void FM_IRQMASK_SET ( FM_ST ST,
int  flag 
)
INLINE void FM_KEYOFF ( FM_CH CH,
int  s 
)
INLINE void FM_KEYON ( UINT8  type,
FM_CH CH,
int  s 
)
INLINE void FM_STATUS_RESET ( FM_ST ST,
int  flag 
)
INLINE void FM_STATUS_SET ( FM_ST ST,
int  flag 
)
static void FMCloseTable ( void  )
static
static int init_tables ( void  )
static
static void init_timetables ( FM_ST ST,
const UINT8 dttable 
)
static
INLINE signed int op_calc ( UINT32  phase,
unsigned int  env,
signed int  pm 
)
INLINE signed int op_calc1 ( UINT32  phase,
unsigned int  env,
signed int  pm 
)
static void OPNSetPres ( FM_OPN OPN,
int  pres,
int  TimerPres,
int  SSGpres 
)
static
static void OPNWriteMode ( FM_OPN OPN,
int  r,
int  v 
)
static
static void OPNWriteReg ( FM_OPN OPN,
int  r,
int  v 
)
static
static void refresh_fc_eg_chan ( FM_OPN OPN,
FM_CH CH 
)
static
INLINE void refresh_fc_eg_slot ( FM_OPN OPN,
FM_SLOT SLOT,
int  fc,
int  kc 
)
static void reset_channels ( FM_ST ST,
FM_CH CH,
int  num 
)
static
INLINE void set_ar_ksr ( UINT8  type,
FM_CH CH,
FM_SLOT SLOT,
int  v 
)
INLINE void set_det_mul ( FM_ST ST,
FM_CH CH,
FM_SLOT SLOT,
int  v 
)
INLINE void set_dr ( UINT8  type,
FM_SLOT SLOT,
int  v 
)
INLINE void set_sl_rr ( UINT8  type,
FM_SLOT SLOT,
int  v 
)
INLINE void set_sr ( UINT8  type,
FM_SLOT SLOT,
int  v 
)
INLINE void set_timers ( FM_ST ST,
int  n,
int  v 
)
INLINE void set_tl ( FM_CH CH,
FM_SLOT SLOT,
int  v 
)
static void setup_connection ( FM_CH CH,
int  ch 
)
static
INLINE void TimerAOver ( FM_ST ST)
INLINE void TimerBOver ( FM_ST ST)
INLINE void update_phase_lfo_channel ( FM_OPN OPN,
FM_CH CH 
)
INLINE void update_phase_lfo_slot ( FM_OPN OPN,
FM_SLOT SLOT,
INT32  pms,
UINT32  block_fnum 
)
void YM2612_dump ( int  num,
uint8_t  buf[512] 
)
void YM2612_restore ( int  num,
uint8_t  buf[512] 
)
int YM2612Init ( int  num,
int  clock,
int  rate,
int  mjazz,
FM_TIMERHANDLER  TimerHandler,
FM_IRQHANDLER  IRQHandler 
)
UINT8 YM2612Read ( int  n,
int  a 
)
void YM2612ResetChip ( int  num)
void YM2612Shutdown ( void  )
int YM2612TimerOver ( int  n,
int  c 
)
void YM2612UpdateOne ( int  num,
INT16 buffer,
unsigned int  length,
unsigned int  volume,
int  loud 
)
int YM2612Write ( int  n,
int  a,
UINT8  v 
)

Variable Documentation

INT32 c1
static
INT32 c2
static
FM_CH* cch[8]
static
void* cur_chip = 0
static
int dacen
static
const UINT8 dt_tab[4 *32]
static
Initial value:
{
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,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
}
const UINT8 eg_inc[19 *RATE_STEPS]
static
Initial value:
{
0,1, 0,1, 0,1, 0,1,
0,1, 0,1, 1,1, 0,1,
0,1, 1,1, 0,1, 1,1,
0,1, 1,1, 1,1, 1,1,
1,1, 1,1, 1,1, 1,1,
1,1, 1,2, 1,1, 1,2,
1,2, 1,2, 1,2, 1,2,
1,2, 2,2, 1,2, 2,2,
2,2, 2,2, 2,2, 2,2,
2,2, 2,4, 2,2, 2,4,
2,4, 2,4, 2,4, 2,4,
2,4, 4,4, 2,4, 4,4,
4,4, 4,4, 4,4, 4,4,
4,4, 4,8, 4,4, 4,8,
4,8, 4,8, 4,8, 4,8,
4,8, 8,8, 4,8, 8,8,
8,8, 8,8, 8,8, 8,8,
16,16,16,16,16,16,16,16,
0,0, 0,0, 0,0, 0,0,
}
const UINT8 eg_rate_select[32+64+32]
static
const UINT8 eg_rate_select2612[32+64+32]
static
const UINT8 eg_rate_shift[32+64+32]
static
YM2612* FM2612 = NULL
static
UINT32 LFO_AM
static
const UINT8 lfo_ams_depth_shift[4] = {8, 3, 1, 0}
static
INT32 LFO_PM
static
const UINT8 lfo_pm_output[7 *8][8]
static
INT32 lfo_pm_table[128 *8 *32]
static
const UINT32 lfo_samples_per_step[8] = {108, 77, 71, 67, 62, 44, 8, 5}
static
INT32 m2
static
INT32 mem
static
const UINT8 opn_fktable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3}
static
INT32 out_fm[8]
static
unsigned int sin_tab[SIN_LEN]
static
const UINT32 sl_table[16]
static
Initial value:
{
SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
}
FM_ST* State
static
signed int tl_tab[TL_TAB_LEN]
static
int YM2612NumChips
static