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