200 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			200 lines
		
	
	
		
			4.7 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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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
							 |