#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_ST * | State |
static FM_CH * | cch [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 YM2612 * | FM2612 = NULL |
static int | dacen |
#define BUILD_OPN (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B||BUILD_YM2612) |
#define BUILD_OPN_PRESCALER (BUILD_YM2203||BUILD_YM2608) |
#define DEBUG_MAX_CHAN 6 |
#define DEBUG_MAX_OPS 4 |
#define DEBUG_PRINT_CHAN_VAL | ( | r, | |
v | |||
) | printf(" %-15s: 0x%02x\n", r, v); |
#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 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 | |||
) |
#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 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 |
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 | ) |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
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 | ||
) |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |