202 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			202 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
 | 
