main ym2612.h
  1/*
  2 Copyright 2013 Michael Pavone
  3 This file is part of BlastEm.
  4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
  5*/
  6#ifndef YM2612_H_
  7#define YM2612_H_
  8
  9#include <stdint.h>
 10#include <stdio.h>
 11#include "serialize.h"
 12#include "render.h"
 13
 14#define NUM_PART_REGS (0xB7-0x30)
 15#define NUM_CHANNELS 6
 16#define NUM_OPERATORS (4*NUM_CHANNELS)
 17
 18#define YM_OPT_WAVE_LOG 1
 19
 20typedef struct {
 21	int16_t  *mod_src[2];
 22	uint32_t phase_counter;
 23	uint16_t envelope;
 24	int16_t  output;
 25	uint16_t total_level;
 26	uint16_t sustain_level;
 27	uint8_t  rates[4];
 28	uint8_t  key_scaling;
 29	uint8_t  multiple;
 30	uint8_t  detune;
 31	uint8_t  am;
 32	uint8_t  env_phase;
 33	uint8_t  ssg;
 34	uint8_t  inverted;
 35} ym_operator;
 36
 37typedef struct {
 38	FILE *   logfile;
 39	uint16_t fnum;
 40	int16_t  output;
 41	int16_t  op1_old;
 42	int16_t  op2_old;
 43	uint8_t  block_fnum_latch;
 44	uint8_t  block;
 45	uint8_t  keycode;
 46	uint8_t  algorithm;
 47	uint8_t  feedback;
 48	uint8_t  ams;
 49	uint8_t  pms;
 50	uint8_t  lr;
 51	uint8_t  keyon;
 52} ym_channel;
 53
 54typedef struct {
 55	uint16_t fnum;
 56	uint8_t  block;
 57	uint8_t  block_fnum_latch;
 58	uint8_t  keycode;
 59} ym_supp;
 60
 61#define YM_PART1_START 0x21
 62#define YM_PART2_START 0x30
 63#define YM_REG_END     0xB8
 64#define YM_PART1_REGS (YM_REG_END-YM_PART1_START)
 65#define YM_PART2_REGS (YM_REG_END-YM_PART2_START)
 66
 67typedef struct {
 68	audio_source *audio;
 69    uint32_t    clock_inc;
 70	uint32_t    current_cycle;
 71	//TODO: Condense the next two fields into one
 72	uint32_t    write_cycle;
 73	uint32_t    busy_cycles;
 74	int32_t     volume_mult;
 75	int32_t     volume_div;
 76	ym_operator operators[NUM_OPERATORS];
 77	ym_channel  channels[NUM_CHANNELS];
 78	int16_t     zero_offset;
 79	uint16_t    timer_a;
 80	uint16_t    timer_a_load;
 81	uint16_t    env_counter;
 82	ym_supp     ch3_supp[3];
 83	uint8_t     timer_b;
 84	uint8_t     sub_timer_b;
 85	uint8_t     timer_b_load;
 86	uint8_t     ch3_mode;
 87	uint8_t     current_op;
 88	uint8_t     current_env_op;
 89
 90	uint8_t     timer_control;
 91	uint8_t     dac_enable;
 92	uint8_t     lfo_enable;
 93	uint8_t     lfo_freq;
 94	uint8_t     lfo_counter;
 95	uint8_t     lfo_am_step;
 96	uint8_t     lfo_pm_step;
 97	uint8_t     csm_keyon;
 98	uint8_t     status;
 99	uint8_t     selected_reg;
100	uint8_t     selected_part;
101	uint8_t     part1_regs[YM_PART1_REGS];
102	uint8_t     part2_regs[YM_PART2_REGS];
103} ym2612_context;
104
105enum {
106	REG_LFO          = 0x22,
107	REG_TIMERA_HIGH  = 0x24,
108	REG_TIMERA_LOW,
109	REG_TIMERB,
110	REG_TIME_CTRL,
111	REG_KEY_ONOFF,
112	REG_DAC          = 0x2A,
113	REG_DAC_ENABLE,
114
115	REG_DETUNE_MULT  = 0x30,
116	REG_TOTAL_LEVEL  = 0x40,
117	REG_ATTACK_KS    = 0x50,
118	REG_DECAY_AM     = 0x60,
119	REG_SUSTAIN_RATE = 0x70,
120	REG_S_LVL_R_RATE = 0x80,
121	REG_SSG_EG       = 0x90,
122
123	REG_FNUM_LOW     = 0xA0,
124	REG_BLOCK_FNUM_H = 0xA4,
125	REG_FNUM_LOW_CH3 = 0xA8,
126	REG_BLOCK_FN_CH3 = 0xAC,
127	REG_ALG_FEEDBACK = 0xB0,
128	REG_LR_AMS_PMS   = 0xB4
129};
130
131void ym_init(ym2612_context * context, uint32_t master_clock, uint32_t clock_div, uint32_t options);
132void ym_reset(ym2612_context *context);
133void ym_free(ym2612_context *context);
134void ym_enable_zero_offset(ym2612_context *context, uint8_t enabled);
135void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock);
136void ym_run(ym2612_context * context, uint32_t to_cycle);
137void ym_address_write_part1(ym2612_context * context, uint8_t address);
138void ym_address_write_part2(ym2612_context * context, uint8_t address);
139void ym_data_write(ym2612_context * context, uint8_t value);
140uint8_t ym_read_status(ym2612_context * context);
141uint8_t ym_load_gst(ym2612_context * context, FILE * gstfile);
142uint8_t ym_save_gst(ym2612_context * context, FILE * gstfile);
143void ym_print_channel_info(ym2612_context *context, int channel);
144void ym_print_timer_info(ym2612_context *context);
145void ym_serialize(ym2612_context *context, serialize_buffer *buf);
146void ym_deserialize(deserialize_buffer *buf, void *vcontext);
147
148#endif //YM2612_H_
149