mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-30 08:23:01 +00:00
b90fb02e63
all features usable, except for custom patchsets (not sure how am i gonna implement it)
201 lines
4.8 KiB
C
201 lines
4.8 KiB
C
/*
|
|
* Copyright (C) 2019 Nuke.YKT
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*
|
|
* Yamaha YM2413 emulator
|
|
* Thanks:
|
|
* siliconpr0n.org(digshadow, John McMaster):
|
|
* VRC VII decap and die shot.
|
|
*
|
|
* version: 1.0.1
|
|
*/
|
|
|
|
#ifndef OPLL_H
|
|
#define OPLL_H
|
|
|
|
#include <stdint.h>
|
|
|
|
enum {
|
|
opll_type_ym2413 = 0x00, /* Yamaha YM2413 */
|
|
opll_type_ds1001, /* Konami VRC VII */
|
|
opll_type_ym2413b, /* Yamaha YM2413B */
|
|
opll_type_ymf281, /* Yamaha YMF281 */
|
|
opll_type_ymf281b, /* Yamaha YMF281B */
|
|
opll_type_ym2420, /* Yamaha YM2420 */
|
|
opll_type_ym2423, /* Yamaha YM2423 */
|
|
};
|
|
|
|
enum {
|
|
opll_patch_1 = 0x00,
|
|
opll_patch_2,
|
|
opll_patch_3,
|
|
opll_patch_4,
|
|
opll_patch_5,
|
|
opll_patch_6,
|
|
opll_patch_7,
|
|
opll_patch_8,
|
|
opll_patch_9,
|
|
opll_patch_10,
|
|
opll_patch_11,
|
|
opll_patch_12,
|
|
opll_patch_13,
|
|
opll_patch_14,
|
|
opll_patch_15,
|
|
opll_patch_drum_0,
|
|
opll_patch_drum_1,
|
|
opll_patch_drum_2,
|
|
opll_patch_drum_3,
|
|
opll_patch_drum_4,
|
|
opll_patch_drum_5,
|
|
opll_patch_max
|
|
};
|
|
|
|
typedef struct {
|
|
uint8_t tl;
|
|
uint8_t dc;
|
|
uint8_t dm;
|
|
uint8_t fb;
|
|
uint8_t am[2];
|
|
uint8_t vib[2];
|
|
uint8_t et[2];
|
|
uint8_t ksr[2];
|
|
uint8_t multi[2];
|
|
uint8_t ksl[2];
|
|
uint8_t ar[2];
|
|
uint8_t dr[2];
|
|
uint8_t sl[2];
|
|
uint8_t rr[2];
|
|
} opll_patch_t;
|
|
|
|
typedef struct {
|
|
uint32_t chip_type;
|
|
uint32_t cycles;
|
|
uint32_t slot;
|
|
const opll_patch_t *patchrom;
|
|
/* IO */
|
|
uint8_t write_data;
|
|
uint8_t write_a;
|
|
uint8_t write_d;
|
|
uint8_t write_a_en;
|
|
uint8_t write_d_en;
|
|
uint8_t write_fm_address;
|
|
uint8_t write_fm_data;
|
|
uint8_t write_mode_address;
|
|
uint8_t address;
|
|
uint8_t data;
|
|
/* Envelope generator */
|
|
uint8_t eg_counter_state;
|
|
uint8_t eg_counter_state_prev;
|
|
uint32_t eg_timer;
|
|
uint8_t eg_timer_low_lock;
|
|
uint8_t eg_timer_carry;
|
|
uint8_t eg_timer_shift;
|
|
uint8_t eg_timer_shift_lock;
|
|
uint8_t eg_timer_shift_stop;
|
|
uint8_t eg_state[18];
|
|
uint8_t eg_level[18];
|
|
uint8_t eg_kon;
|
|
uint32_t eg_dokon;
|
|
uint8_t eg_off;
|
|
uint8_t eg_rate;
|
|
uint8_t eg_maxrate;
|
|
uint8_t eg_zerorate;
|
|
uint8_t eg_inc_lo;
|
|
uint8_t eg_inc_hi;
|
|
uint8_t eg_rate_hi;
|
|
uint16_t eg_sl;
|
|
uint16_t eg_ksltl;
|
|
uint8_t eg_out;
|
|
uint8_t eg_silent;
|
|
/* Phase generator */
|
|
uint16_t pg_fnum;
|
|
uint8_t pg_block;
|
|
uint16_t pg_out;
|
|
uint32_t pg_inc;
|
|
uint32_t pg_phase[18];
|
|
uint32_t pg_phase_next;
|
|
/* Operator */
|
|
int16_t op_fb1[9];
|
|
int16_t op_fb2[9];
|
|
int16_t op_fbsum;
|
|
int16_t op_mod;
|
|
uint8_t op_neg;
|
|
uint16_t op_logsin;
|
|
uint16_t op_exp_m;
|
|
uint16_t op_exp_s;
|
|
/* Channel */
|
|
int16_t ch_out;
|
|
int16_t ch_out_hh;
|
|
int16_t ch_out_tm;
|
|
int16_t ch_out_bd;
|
|
int16_t ch_out_sd;
|
|
int16_t ch_out_tc;
|
|
/* LFO */
|
|
uint16_t lfo_counter;
|
|
uint8_t lfo_vib_counter;
|
|
uint16_t lfo_am_counter;
|
|
uint8_t lfo_am_step;
|
|
uint8_t lfo_am_dir;
|
|
uint8_t lfo_am_car;
|
|
uint8_t lfo_am_out;
|
|
/* Register set */
|
|
uint16_t fnum[9];
|
|
uint8_t block[9];
|
|
uint8_t kon[9];
|
|
uint8_t son[9];
|
|
uint8_t vol[9];
|
|
uint8_t inst[9];
|
|
uint8_t rhythm;
|
|
uint8_t testmode;
|
|
opll_patch_t patch;
|
|
uint8_t c_instr;
|
|
uint8_t c_op;
|
|
uint8_t c_tl;
|
|
uint8_t c_dc;
|
|
uint8_t c_dm;
|
|
uint8_t c_fb;
|
|
uint8_t c_am;
|
|
uint8_t c_vib;
|
|
uint8_t c_et;
|
|
uint8_t c_ksr;
|
|
uint8_t c_ksr_freq;
|
|
uint8_t c_ksl_freq;
|
|
uint8_t c_ksl_block;
|
|
uint8_t c_multi;
|
|
uint8_t c_ksl;
|
|
uint8_t c_adrr[3];
|
|
uint8_t c_sl;
|
|
uint16_t c_fnum;
|
|
uint16_t c_block;
|
|
/* Rhythm mode */
|
|
int8_t rm_enable;
|
|
uint32_t rm_noise;
|
|
uint32_t rm_select;
|
|
uint8_t rm_hh_bit2;
|
|
uint8_t rm_hh_bit3;
|
|
uint8_t rm_hh_bit7;
|
|
uint8_t rm_hh_bit8;
|
|
uint8_t rm_tc_bit3;
|
|
uint8_t rm_tc_bit5;
|
|
|
|
int16_t output_m;
|
|
int16_t output_r;
|
|
|
|
} opll_t;
|
|
|
|
const opll_patch_t* OPLL_GetPatchROM(uint32_t chip_type);
|
|
|
|
void OPLL_Reset(opll_t *chip, uint32_t chip_type);
|
|
void OPLL_Clock(opll_t *chip, int32_t *buffer);
|
|
void OPLL_Write(opll_t *chip, uint32_t port, uint8_t data);
|
|
#endif
|