main ym2612.c
   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#include <string.h>
   7#include <math.h>
   8#include <stdio.h>
   9#include <stdlib.h>
  10#include "ym2612.h"
  11#include "render.h"
  12#include "wave.h"
  13#include "blastem.h"
  14
  15//#define DO_DEBUG_PRINT
  16#ifdef DO_DEBUG_PRINT
  17#define dfprintf fprintf
  18#define dfopen(var, fname, mode) var=fopen(fname, mode)
  19#else
  20#define dfprintf
  21#define dfopen(var, fname, mode)
  22#endif
  23
  24#define BUSY_CYCLES_ADDRESS 17
  25#define BUSY_CYCLES_DATA_LOW 83
  26#define BUSY_CYCLES_DATA_HIGH 47
  27#define OP_UPDATE_PERIOD 144
  28
  29#define BIT_TIMERA_ENABLE 0x1
  30#define BIT_TIMERB_ENABLE 0x2
  31#define BIT_TIMERA_OVEREN 0x4
  32#define BIT_TIMERB_OVEREN 0x8
  33#define BIT_TIMERA_RESET  0x10
  34#define BIT_TIMERB_RESET  0x20
  35
  36#define BIT_TIMERA_LOAD   0x40
  37#define BIT_TIMERB_LOAD   0x80
  38
  39#define BIT_STATUS_TIMERA 0x1
  40#define BIT_STATUS_TIMERB 0x2
  41
  42static uint32_t ym_calc_phase_inc(ym2612_context * context, ym_operator * operator, uint32_t op);
  43
  44enum {
  45	PHASE_ATTACK,
  46	PHASE_DECAY,
  47	PHASE_SUSTAIN,
  48	PHASE_RELEASE
  49};
  50
  51uint8_t did_tbl_init = 0;
  52//According to Nemesis, real hardware only uses a 256 entry quarter sine table; however,
  53//memory is cheap so using a half sine table will probably save some cycles
  54//a full sine table would be nice, but negative numbers don't get along with log2
  55#define SINE_TABLE_SIZE 512
  56static uint16_t sine_table[SINE_TABLE_SIZE];
  57//Similar deal here with the power table for log -> linear conversion
  58//According to Nemesis, real hardware only uses a 256 entry table for the fractional part
  59//and uses the whole part as a shift amount.
  60#define POW_TABLE_SIZE (1 << 13)
  61static uint16_t pow_table[POW_TABLE_SIZE];
  62
  63static uint16_t rate_table_base[] = {
  64	//main portion
  65	0,1,0,1,0,1,0,1,
  66	0,1,0,1,1,1,0,1,
  67	0,1,1,1,0,1,1,1,
  68	0,1,1,1,1,1,1,1,
  69	//top end
  70	1,1,1,1,1,1,1,1,
  71	1,1,1,2,1,1,1,2,
  72	1,2,1,2,1,2,1,2,
  73	1,2,2,2,1,2,2,2,
  74};
  75
  76static uint16_t rate_table[64*8];
  77
  78static uint8_t lfo_timer_values[] = {108, 77, 71, 67, 62, 44, 8, 5};
  79static uint8_t lfo_pm_base[][8] = {
  80	{0,   0,   0,   0,   0,   0,   0,   0},
  81	{0,   0,   0,   0,   4,   4,   4,   4},
  82	{0,   0,   0,   4,   4,   4,   8,   8},
  83	{0,   0,   4,   4,   8,   8, 0xc, 0xc},
  84	{0,   0,   4,   8,   8,   8, 0xc,0x10},
  85	{0,   0,   8, 0xc,0x10,0x10,0x14,0x18},
  86	{0,   0,0x10,0x18,0x20,0x20,0x28,0x30},
  87	{0,   0,0x20,0x30,0x40,0x40,0x50,0x60}
  88};
  89static int16_t lfo_pm_table[128 * 32 * 8];
  90
  91int16_t ams_shift[] = {8, 1, -1, -2};
  92
  93#define MAX_ENVELOPE 0xFFC
  94#define YM_DIVIDER 2
  95#define CYCLE_NEVER 0xFFFFFFFF
  96
  97static uint16_t round_fixed_point(double value, int dec_bits)
  98{
  99	return value * (1 << dec_bits) + 0.5;
 100}
 101
 102static FILE * debug_file = NULL;
 103static uint32_t first_key_on=0;
 104
 105static ym2612_context * log_context = NULL;
 106
 107static void ym_finalize_log()
 108{
 109	if (!log_context) {
 110		return;
 111	}
 112	for (int i = 0; i < NUM_CHANNELS; i++) {
 113		if (log_context->channels[i].logfile) {
 114			wave_finalize(log_context->channels[i].logfile);
 115		}
 116	}
 117	log_context = NULL;
 118}
 119
 120void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock)
 121{
 122	render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * NUM_OPERATORS);
 123}
 124
 125#define TIMER_A_MAX 1023
 126#define TIMER_B_MAX 255
 127
 128void ym_reset(ym2612_context *context)
 129{
 130	memset(context->part1_regs, 0, sizeof(context->part1_regs));
 131	memset(context->part2_regs, 0, sizeof(context->part2_regs));
 132	memset(context->operators, 0, sizeof(context->operators));
 133	FILE* savedlogs[NUM_CHANNELS];
 134	for (int i = 0; i < NUM_CHANNELS; i++)
 135	{
 136		savedlogs[i] = context->channels[i].logfile;
 137	}
 138	memset(context->channels, 0, sizeof(context->channels));
 139	memset(context->ch3_supp, 0, sizeof(context->ch3_supp));
 140	context->selected_reg = 0;
 141	context->csm_keyon = 0;
 142	context->ch3_mode = 0;
 143	context->dac_enable = 0;
 144	context->status = 0;
 145	context->timer_a_load = 0;
 146	context->timer_b_load = 0;
 147	//TODO: Confirm these on hardware
 148	context->timer_a = TIMER_A_MAX;
 149	context->timer_b = TIMER_B_MAX;
 150	
 151	//TODO: Reset LFO state
 152	
 153	//some games seem to expect that the LR flags start out as 1
 154	for (int i = 0; i < NUM_CHANNELS; i++) {
 155		context->channels[i].lr = 0xC0;
 156		context->channels[i].logfile = savedlogs[i];
 157	}
 158	context->write_cycle = CYCLE_NEVER;
 159	for (int i = 0; i < NUM_OPERATORS; i++) {
 160		context->operators[i].envelope = MAX_ENVELOPE;
 161		context->operators[i].env_phase = PHASE_RELEASE;
 162	}
 163}
 164
 165void ym_init(ym2612_context * context, uint32_t master_clock, uint32_t clock_div, uint32_t options)
 166{
 167	static uint8_t registered_finalize;
 168	dfopen(debug_file, "ym_debug.txt", "w");
 169	memset(context, 0, sizeof(*context));
 170	context->clock_inc = clock_div * 6;
 171	context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2);
 172	
 173	//some games seem to expect that the LR flags start out as 1
 174	for (int i = 0; i < NUM_CHANNELS; i++) {
 175		if (options & YM_OPT_WAVE_LOG) {
 176			char fname[64];
 177			sprintf(fname, "ym_channel_%d.wav", i);
 178			FILE * f = context->channels[i].logfile = fopen(fname, "wb");
 179			if (!f) {
 180				fprintf(stderr, "Failed to open WAVE log file %s for writing\n", fname);
 181				continue;
 182			}
 183			if (!wave_init(f, master_clock / (context->clock_inc * NUM_OPERATORS), 16, 1)) {
 184				fclose(f);
 185				context->channels[i].logfile = NULL;
 186			}
 187		}
 188	}
 189	if (options & YM_OPT_WAVE_LOG) {
 190		log_context = context;
 191		if (!registered_finalize) {
 192			atexit(ym_finalize_log);
 193			registered_finalize = 1;
 194		}
 195	}
 196	if (!did_tbl_init) {
 197		//populate sine table
 198		for (int32_t i = 0; i < 512; i++) {
 199			double sine = sin( ((double)(i*2+1) / SINE_TABLE_SIZE) * M_PI_2 );
 200
 201			//table stores 4.8 fixed pointed representation of the base 2 log
 202			sine_table[i] = round_fixed_point(-log2(sine), 8);
 203		}
 204		//populate power table
 205		for (int32_t i = 0; i < POW_TABLE_SIZE; i++) {
 206			double linear = pow(2, -((double)((i & 0xFF)+1) / 256.0));
 207			int32_t tmp = round_fixed_point(linear, 11);
 208			int32_t shift = (i >> 8) - 2;
 209			if (shift < 0) {
 210				tmp <<= 0-shift;
 211			} else {
 212				tmp >>= shift;
 213			}
 214			pow_table[i] =  tmp;
 215		}
 216		//populate envelope generator rate table, from small base table
 217		for (int rate = 0; rate < 64; rate++) {
 218			for (int cycle = 0; cycle < 8; cycle++) {
 219				uint16_t value;
 220				if (rate < 2) {
 221					value = 0;
 222				} else if (rate >= 60) {
 223					value = 8;
 224				} else if (rate < 8) {
 225					value = rate_table_base[((rate & 6) == 6 ? 16 : 0) + cycle];
 226				} else if (rate < 48) {
 227					value = rate_table_base[(rate & 0x3) * 8 + cycle];
 228				} else {
 229					value = rate_table_base[32 + (rate & 0x3) * 8 + cycle] << ((rate - 48) >> 2);
 230				}
 231				rate_table[rate * 8 + cycle] = value;
 232			}
 233		}
 234		//populate LFO PM table from small base table
 235		//seems like there must be a better way to derive this
 236		for (int freq = 0; freq < 128; freq++) {
 237			for (int pms = 0; pms < 8; pms++) {
 238				for (int step = 0; step < 32; step++) {
 239					int16_t value = 0;
 240					for (int bit = 0x40, shift = 0; bit > 0; bit >>= 1, shift++) {
 241						if (freq & bit) {
 242							value += lfo_pm_base[pms][(step & 0x8) ? 7-step & 7 : step & 7] >> shift;
 243						}
 244					}
 245					if (step & 0x10) {
 246						value = -value;
 247					}
 248					lfo_pm_table[freq * 256 + pms * 32 + step] = value;
 249				}
 250			}
 251		}
 252	}
 253	ym_reset(context);
 254	ym_enable_zero_offset(context, 1);
 255}
 256
 257void ym_free(ym2612_context *context)
 258{
 259	render_free_source(context->audio);
 260	if (context == log_context) {
 261		ym_finalize_log();
 262	}
 263	free(context);
 264}
 265
 266void ym_enable_zero_offset(ym2612_context *context, uint8_t enabled)
 267{
 268	if (enabled) {
 269		context->zero_offset = 0x70;
 270		context->volume_mult = 79;
 271		context->volume_div = 120;
 272	} else {
 273		context->zero_offset = 0;
 274		context->volume_mult = 2;
 275		context->volume_div = 3;
 276	}
 277}
 278#define YM_MOD_SHIFT 1
 279
 280#define CSM_MODE 0x80
 281
 282#define SSG_ENABLE    8
 283#define SSG_INVERT    4
 284#define SSG_ALTERNATE 2
 285#define SSG_HOLD      1
 286
 287#define SSG_CENTER 0x800
 288
 289static void start_envelope(ym_operator *op, ym_channel *channel)
 290{
 291	//Deal with "infinite" attack rates
 292	uint8_t rate = op->rates[PHASE_ATTACK];
 293	if (rate) {
 294		uint8_t ks = channel->keycode >> op->key_scaling;;
 295		rate = rate*2 + ks;
 296	}
 297	if (rate >= 62) {
 298		op->env_phase = PHASE_DECAY;
 299		op->envelope = 0;
 300	} else {
 301		op->env_phase = PHASE_ATTACK;
 302	}
 303}
 304
 305static void keyon(ym_operator *op, ym_channel *channel)
 306{
 307	start_envelope(op, channel);
 308	op->phase_counter = 0;
 309	op->inverted = op->ssg & SSG_INVERT;
 310}
 311
 312static const uint8_t keyon_bits[] = {0x10, 0x40, 0x20, 0x80};
 313
 314static void keyoff(ym_operator *op)
 315{
 316	op->env_phase = PHASE_RELEASE;
 317	if (op->inverted) {
 318		//Nemesis says the inversion state doesn't change here, but I don't see how that is observable either way
 319		op->inverted = 0;
 320		op->envelope = (SSG_CENTER - op->envelope) & MAX_ENVELOPE;
 321	}
 322}
 323
 324static void csm_keyoff(ym2612_context *context)
 325{
 326	context->csm_keyon = 0;
 327	uint8_t changes = 0xF0 ^ context->channels[2].keyon;
 328	for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++)
 329	{
 330		if (changes & keyon_bits[bit]) {
 331			keyoff(context->operators + op);
 332		}
 333	}
 334}
 335
 336void ym_run(ym2612_context * context, uint32_t to_cycle)
 337{
 338	//printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle);
 339	//TODO: Fix channel update order OR remap channels in register write
 340	for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) {
 341		//Update timers at beginning of 144 cycle period
 342		if (!context->current_op) {
 343			if (context->timer_control & BIT_TIMERA_ENABLE) {
 344				if (context->timer_a != TIMER_A_MAX) {
 345					context->timer_a++;
 346					if (context->csm_keyon) {
 347						csm_keyoff(context);
 348					}
 349				} else {
 350					if (context->timer_control & BIT_TIMERA_LOAD) {
 351						context->timer_control &= ~BIT_TIMERA_LOAD;
 352					} else if (context->timer_control & BIT_TIMERA_OVEREN) {
 353						context->status |= BIT_STATUS_TIMERA;
 354					}
 355					context->timer_a = context->timer_a_load;
 356					if (!context->csm_keyon && context->ch3_mode == CSM_MODE) {
 357						context->csm_keyon = 0xF0;
 358						uint8_t changes = 0xF0 ^ context->channels[2].keyon;;
 359						for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++)
 360						{
 361							if (changes & keyon_bits[bit]) {
 362								keyon(context->operators + op, context->channels + 2);
 363							}
 364						}
 365					}
 366				}
 367			}
 368			if (!context->sub_timer_b) {
 369				if (context->timer_control & BIT_TIMERB_ENABLE) {
 370					if (context->timer_b != TIMER_B_MAX) {
 371						context->timer_b++;
 372					} else {
 373						if (context->timer_control & BIT_TIMERB_LOAD) {
 374							context->timer_control &= ~BIT_TIMERB_LOAD;
 375						} else if (context->timer_control & BIT_TIMERB_OVEREN) {
 376							context->status |= BIT_STATUS_TIMERB;
 377						}
 378						context->timer_b = context->timer_b_load;
 379					}
 380				}
 381			}
 382			context->sub_timer_b += 0x10;
 383			//Update LFO
 384			if (context->lfo_enable) {
 385				if (context->lfo_counter) {
 386					context->lfo_counter--;
 387				} else {
 388					context->lfo_counter = lfo_timer_values[context->lfo_freq];
 389					context->lfo_am_step += 2;
 390					context->lfo_am_step &= 0xFE;
 391					context->lfo_pm_step = context->lfo_am_step / 8;
 392				}
 393			}
 394		}
 395		//Update Envelope Generator
 396		if (!(context->current_op % 3)) {
 397			uint32_t env_cyc = context->env_counter;
 398			uint32_t op = context->current_env_op;
 399			ym_operator * operator = context->operators + op;
 400			ym_channel * channel = context->channels + op/4;
 401			uint8_t rate;
 402			if (operator->env_phase == PHASE_DECAY && operator->envelope >= operator->sustain_level) {
 403				//operator->envelope = operator->sustain_level;
 404				operator->env_phase = PHASE_SUSTAIN;
 405			}
 406			rate = operator->rates[operator->env_phase];
 407			if (rate) {
 408				uint8_t ks = channel->keycode >> operator->key_scaling;;
 409				rate = rate*2 + ks;
 410				if (rate > 63) {
 411					rate = 63;
 412				}
 413			}
 414			uint32_t cycle_shift = rate < 0x30 ? ((0x2F - rate) >> 2) : 0;
 415			if (first_key_on) {
 416				dfprintf(debug_file, "Operator: %d, env rate: %d (2*%d+%d), env_cyc: %d, cycle_shift: %d, env_cyc & ((1 << cycle_shift) - 1): %d\n", op, rate, operator->rates[operator->env_phase], channel->keycode >> operator->key_scaling,env_cyc, cycle_shift, env_cyc & ((1 << cycle_shift) - 1));
 417			}
 418			if (!(env_cyc & ((1 << cycle_shift) - 1))) {
 419				uint32_t update_cycle = env_cyc >> cycle_shift & 0x7;
 420				uint16_t envelope_inc = rate_table[rate * 8 + update_cycle];
 421				if (operator->env_phase == PHASE_ATTACK) {
 422					//this can probably be optimized to a single shift rather than a multiply + shift
 423					if (first_key_on) {
 424						dfprintf(debug_file, "Changing op %d envelope %d by %d(%d * %d) in attack phase\n", op, operator->envelope, (~operator->envelope * envelope_inc) >> 4, ~operator->envelope, envelope_inc);
 425					}
 426					uint16_t old_env = operator->envelope;
 427					operator->envelope += ((~operator->envelope * envelope_inc) >> 4) & 0xFFFFFFFC;
 428					if (operator->envelope > old_env) {
 429						//Handle overflow
 430						operator->envelope = 0;
 431					}
 432					if (!operator->envelope) {
 433						operator->env_phase = PHASE_DECAY;
 434					}
 435				} else {
 436					if (first_key_on) {
 437						dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc,
 438							operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release"));
 439					}
 440					if (operator->ssg) {
 441						if (operator->envelope < SSG_CENTER) {
 442							envelope_inc *= 4;
 443						} else {
 444							envelope_inc = 0;
 445						}
 446					}
 447					//envelope value is 10-bits, but it will be used as a 4.8 value
 448					operator->envelope += envelope_inc << 2;
 449					//clamp to max attenuation value
 450					if (
 451						operator->envelope > MAX_ENVELOPE 
 452						|| (operator->env_phase == PHASE_RELEASE && operator->envelope >= SSG_CENTER)
 453					) {
 454						operator->envelope = MAX_ENVELOPE;
 455					}
 456				}
 457			}
 458			context->current_env_op++;
 459			if (context->current_env_op == NUM_OPERATORS) {
 460				context->current_env_op = 0;
 461				context->env_counter++;
 462			}
 463		}
 464
 465		//Update Phase Generator
 466		uint32_t channel = context->current_op / 4;
 467		if (channel != 5 || !context->dac_enable) {
 468			uint32_t op = context->current_op;
 469			//printf("updating operator %d of channel %d\n", op, channel);
 470			ym_operator * operator = context->operators + op;
 471			ym_channel * chan = context->channels + channel;
 472			uint16_t phase = operator->phase_counter >> 10 & 0x3FF;
 473			operator->phase_counter += ym_calc_phase_inc(context, operator, context->current_op);
 474			int16_t mod = 0;
 475			if (op & 3) {
 476				if (operator->mod_src[0]) {
 477					mod = *operator->mod_src[0];
 478					if (operator->mod_src[1]) {
 479						mod += *operator->mod_src[1];
 480					}
 481					mod >>= YM_MOD_SHIFT;
 482				}
 483			} else {
 484				if (chan->feedback) {
 485					mod = (chan->op1_old + operator->output) >> (10-chan->feedback);
 486				}
 487			}
 488			uint16_t env = operator->envelope;
 489			if (operator->ssg) {
 490				if (env >= SSG_CENTER) {
 491					if (operator->ssg & SSG_ALTERNATE) {
 492						if (operator->env_phase != PHASE_RELEASE && (
 493							!(operator->ssg & SSG_HOLD) || ((operator->ssg ^ operator->inverted) & SSG_INVERT) == 0
 494						)) {
 495							operator->inverted ^= SSG_INVERT;
 496						}
 497					} else if (!(operator->ssg & SSG_HOLD)) {
 498						phase = operator->phase_counter = 0;
 499					}
 500					if (
 501						(operator->env_phase == PHASE_DECAY || operator->env_phase == PHASE_SUSTAIN) 
 502						&& !(operator->ssg & SSG_HOLD)
 503					) {
 504						start_envelope(operator, chan);
 505						env = operator->envelope;
 506					}
 507				}
 508				if (operator->inverted) {
 509					env = (SSG_CENTER - env) & MAX_ENVELOPE;
 510				}
 511			}
 512			env += operator->total_level;
 513			if (operator->am) {
 514				uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E;
 515				if (ams_shift[chan->ams] >= 0) {
 516					env += (base_am >> ams_shift[chan->ams]) & MAX_ENVELOPE;
 517				} else {
 518					env += base_am << (-ams_shift[chan->ams]);
 519				}
 520			}
 521			if (env > MAX_ENVELOPE) {
 522				env = MAX_ENVELOPE;
 523			}
 524			if (first_key_on) {
 525				dfprintf(debug_file, "op %d, base phase: %d, mod: %d, sine: %d, out: %d\n", op, phase, mod, sine_table[(phase+mod) & 0x1FF], pow_table[sine_table[phase & 0x1FF] + env]);
 526			}
 527			//if ((channel != 0 && channel != 4) || chan->algorithm != 5) {
 528				phase += mod;
 529			//}
 530
 531			int16_t output = pow_table[sine_table[phase & 0x1FF] + env];
 532			if (phase & 0x200) {
 533				output = -output;
 534			}
 535			if (op % 4 == 0) {
 536				chan->op1_old = operator->output;
 537			} else if (op % 4 == 2) {
 538				chan->op2_old = operator->output;
 539			}
 540			operator->output = output;
 541			//Update the channel output if we've updated all operators
 542			if (op % 4 == 3) {
 543				if (chan->algorithm < 4) {
 544					chan->output = operator->output;
 545				} else if(chan->algorithm == 4) {
 546					chan->output = operator->output + context->operators[channel * 4 + 2].output;
 547				} else {
 548					output = 0;
 549					for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) {
 550						output += context->operators[op].output;
 551					}
 552					chan->output = output;
 553				}
 554				if (first_key_on) {
 555					int16_t value = context->channels[channel].output & 0x3FE0;
 556					if (value & 0x2000) {
 557						value |= 0xC000;
 558					}
 559					dfprintf(debug_file, "channel %d output: %d\n", channel, (value * context->volume_mult) / context->volume_div);
 560				}
 561			}
 562			//puts("operator update done");
 563		}
 564		context->current_op++;
 565		if (context->current_op == NUM_OPERATORS) {
 566			context->current_op = 0;
 567			
 568			int16_t left = 0, right = 0;
 569			for (int i = 0; i < NUM_CHANNELS; i++) {
 570				int16_t value = context->channels[i].output;
 571				if (value > 0x1FE0) {
 572					value = 0x1FE0;
 573				} else if (value < -0x1FF0) {
 574					value = -0x1FF0;
 575				} else {
 576					value &= 0x3FE0;
 577					if (value & 0x2000) {
 578						value |= 0xC000;
 579					}
 580				}
 581				if (value >= 0) {
 582					value += context->zero_offset;
 583				} else {
 584					value -= context->zero_offset;
 585				}
 586				if (context->channels[i].logfile) {
 587					fwrite(&value, sizeof(value), 1, context->channels[i].logfile);
 588				}
 589				if (context->channels[i].lr & 0x80) {
 590					left += (value * context->volume_mult) / context->volume_div;
 591				} else if (context->zero_offset) {
 592					if (value >= 0) {
 593						left += (context->zero_offset * context->volume_mult) / context->volume_div;
 594					} else {
 595						left -= (context->zero_offset * context->volume_mult) / context->volume_div;
 596					}
 597				}
 598				if (context->channels[i].lr & 0x40) {
 599					right += (value * context->volume_mult) / context->volume_div;
 600				} else if (context->zero_offset) {
 601					if (value >= 0) {
 602						right += (context->zero_offset * context->volume_mult) / context->volume_div;
 603					} else {
 604						right -= (context->zero_offset * context->volume_mult) / context->volume_div;
 605					}
 606				}
 607			}
 608			render_put_stereo_sample(context->audio, left, right);
 609		}
 610		
 611	}
 612	if (context->current_cycle >= context->write_cycle + (context->busy_cycles * context->clock_inc / 6)) {
 613		context->status &= 0x7F;
 614		context->write_cycle = CYCLE_NEVER;
 615	}
 616	//printf("Done running YM2612 at cycle %d\n", context->current_cycle, to_cycle);
 617}
 618
 619void ym_address_write_part1(ym2612_context * context, uint8_t address)
 620{
 621	//printf("address_write_part1: %X\n", address);
 622	context->selected_reg = address;
 623	context->selected_part = 0;
 624	context->write_cycle = context->current_cycle;
 625	context->busy_cycles = BUSY_CYCLES_ADDRESS;
 626	context->status |= 0x80;
 627}
 628
 629void ym_address_write_part2(ym2612_context * context, uint8_t address)
 630{
 631	//printf("address_write_part2: %X\n", address);
 632	context->selected_reg = address;
 633	context->selected_part = 1;
 634	context->write_cycle = context->current_cycle;
 635	context->busy_cycles = BUSY_CYCLES_ADDRESS;
 636	context->status |= 0x80;
 637}
 638
 639static uint8_t fnum_to_keycode[] = {
 640	//F11 = 0
 641	0,0,0,0,0,0,0,1,
 642	//F11 = 1
 643	2,3,3,3,3,3,3,3
 644};
 645
 646//table courtesy of Nemesis
 647static uint32_t detune_table[][4] = {
 648	{0, 0, 1, 2},   //0  (0x00)
 649    {0, 0, 1, 2},   //1  (0x01)
 650    {0, 0, 1, 2},   //2  (0x02)
 651    {0, 0, 1, 2},   //3  (0x03)
 652    {0, 1, 2, 2},   //4  (0x04)
 653    {0, 1, 2, 3},   //5  (0x05)
 654    {0, 1, 2, 3},   //6  (0x06)
 655    {0, 1, 2, 3},   //7  (0x07)
 656    {0, 1, 2, 4},   //8  (0x08)
 657    {0, 1, 3, 4},   //9  (0x09)
 658    {0, 1, 3, 4},   //10 (0x0A)
 659    {0, 1, 3, 5},   //11 (0x0B)
 660    {0, 2, 4, 5},   //12 (0x0C)
 661    {0, 2, 4, 6},   //13 (0x0D)
 662    {0, 2, 4, 6},   //14 (0x0E)
 663    {0, 2, 5, 7},   //15 (0x0F)
 664    {0, 2, 5, 8},   //16 (0x10)
 665    {0, 3, 6, 8},   //17 (0x11)
 666    {0, 3, 6, 9},   //18 (0x12)
 667    {0, 3, 7,10},   //19 (0x13)
 668    {0, 4, 8,11},   //20 (0x14)
 669    {0, 4, 8,12},   //21 (0x15)
 670    {0, 4, 9,13},   //22 (0x16)
 671    {0, 5,10,14},   //23 (0x17)
 672    {0, 5,11,16},   //24 (0x18)
 673    {0, 6,12,17},   //25 (0x19)
 674    {0, 6,13,19},   //26 (0x1A)
 675    {0, 7,14,20},   //27 (0x1B)
 676    {0, 8,16,22},   //28 (0x1C)
 677    {0, 8,16,22},   //29 (0x1D)
 678    {0, 8,16,22},   //30 (0x1E)
 679    {0, 8,16,22}
 680};  //31 (0x1F)
 681
 682static uint32_t ym_calc_phase_inc(ym2612_context * context, ym_operator * operator, uint32_t op)
 683{
 684	uint32_t chan_num = op / 4;
 685	//printf("ym_update_phase_inc | channel: %d, op: %d\n", chan_num, op);
 686	//base frequency
 687	ym_channel * channel = context->channels + chan_num;
 688	uint32_t inc, detune;
 689	if (chan_num == 2 && context->ch3_mode && (op < (2*4 + 3))) {
 690		//supplemental fnum registers are in a different order than normal slot paramters
 691		int index = op-2*4;
 692		if (index < 2) {
 693			index ^= 1;
 694		}
 695		inc = context->ch3_supp[index].fnum;
 696		if (channel->pms) {
 697			inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step];
 698			inc &= 0xFFF;
 699		}
 700		if (!context->ch3_supp[index].block) {
 701			inc >>= 1;
 702		} else {
 703			inc <<= (context->ch3_supp[index].block-1);
 704		}
 705		//detune
 706		detune = detune_table[context->ch3_supp[index].keycode][operator->detune & 0x3];
 707	} else {
 708		inc = channel->fnum;
 709		if (channel->pms) {
 710			inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step];
 711			inc &= 0xFFF;
 712		}
 713		if (!channel->block) {
 714			inc >>= 1;
 715		} else {
 716			inc <<= (channel->block-1);
 717		}
 718		//detune
 719		detune = detune_table[channel->keycode][operator->detune & 0x3];
 720	}
 721	if (channel->pms) {
 722		inc >>= 1;
 723	}
 724	if (operator->detune & 0x4) {
 725		inc -= detune;
 726		//this can underflow, mask to 17-bit result
 727		inc &= 0x1FFFF;
 728	} else {
 729		inc += detune;
 730	}
 731	//multiple
 732	if (operator->multiple) {
 733		inc *= operator->multiple;
 734		inc &= 0xFFFFF;
 735	} else {
 736		//0.5
 737		inc >>= 1;
 738	}
 739	//printf("phase_inc for operator %d: %d, block: %d, fnum: %d, detune: %d, multiple: %d\n", op, inc, channel->block, channel->fnum, detune, operator->multiple);
 740	return inc;
 741}
 742
 743void ym_data_write(ym2612_context * context, uint8_t value)
 744{
 745	if (context->selected_reg >= YM_REG_END) {
 746		return;
 747	}
 748	if (context->selected_part) {
 749		if (context->selected_reg < YM_PART2_START) {
 750			return;
 751		}
 752		context->part2_regs[context->selected_reg - YM_PART2_START] = value;
 753	} else {
 754		if (context->selected_reg < YM_PART1_START) {
 755			return;
 756		}
 757		context->part1_regs[context->selected_reg - YM_PART1_START] = value;
 758	}
 759	dfprintf(debug_file, "write of %X to reg %X in part %d\n", value, context->selected_reg, context->selected_part+1);
 760	if (context->selected_reg < 0x30) {
 761		//Shared regs
 762		switch (context->selected_reg)
 763		{
 764		//TODO: Test reg
 765		case REG_LFO:
 766			/*if ((value & 0x8) && !context->lfo_enable) {
 767				printf("LFO Enabled, Freq: %d\n", value & 0x7);
 768			}*/
 769			context->lfo_enable = value & 0x8;
 770			if (!context->lfo_enable) {
 771				context->lfo_am_step = context->lfo_pm_step = 0;
 772			}
 773			context->lfo_freq = value & 0x7;
 774
 775			break;
 776		case REG_TIMERA_HIGH:
 777			context->timer_a_load &= 0x3;
 778			context->timer_a_load |= value << 2;
 779			break;
 780		case REG_TIMERA_LOW:
 781			context->timer_a_load &= 0xFFFC;
 782			context->timer_a_load |= value & 0x3;
 783			break;
 784		case REG_TIMERB:
 785			context->timer_b_load = value;
 786			break;
 787		case REG_TIME_CTRL: {
 788			if (value & BIT_TIMERA_ENABLE && !(context->timer_control & BIT_TIMERA_ENABLE)) {
 789				context->timer_a = TIMER_A_MAX;
 790				context->timer_control |= BIT_TIMERA_LOAD;
 791			}
 792			if (value & BIT_TIMERB_ENABLE && !(context->timer_control & BIT_TIMERB_ENABLE)) {
 793				context->timer_b = TIMER_B_MAX;
 794				context->timer_control |= BIT_TIMERB_LOAD;
 795			}
 796			context->timer_control &= (BIT_TIMERA_LOAD | BIT_TIMERB_LOAD);
 797			context->timer_control |= value & 0xF;
 798			if (value & BIT_TIMERA_RESET) {
 799				context->status &= ~BIT_STATUS_TIMERA;
 800			}
 801			if (value & BIT_TIMERB_RESET) {
 802				context->status &= ~BIT_STATUS_TIMERB;
 803			}
 804			if (context->ch3_mode == CSM_MODE && (value & 0xC0) != CSM_MODE && context->csm_keyon) {
 805				csm_keyoff(context);
 806			}
 807			context->ch3_mode = value & 0xC0;
 808			break;
 809		}
 810		case REG_KEY_ONOFF: {
 811			uint8_t channel = value & 0x7;
 812			if (channel != 3 && channel != 7) {
 813				if (channel > 2) {
 814					channel--;
 815				}
 816				uint8_t changes = channel == 2 
 817					? (value | context->csm_keyon) ^  (context->channels[channel].keyon | context->csm_keyon)
 818					: value ^ context->channels[channel].keyon;
 819				context->channels[channel].keyon = value & 0xF0;
 820				for (uint8_t op = channel * 4, bit = 0; op < (channel + 1) * 4; op++, bit++) {
 821					if (changes & keyon_bits[bit]) {
 822						if (value & keyon_bits[bit]) {
 823							first_key_on = 1;
 824							//printf("Key On for operator %d in channel %d\n", op, channel);
 825							keyon(context->operators + op, context->channels + channel);
 826						} else {
 827							//printf("Key Off for operator %d in channel %d\n", op, channel);
 828							keyoff(context->operators + op);
 829						}
 830					}
 831				}
 832			}
 833			break;
 834		}
 835		case REG_DAC:
 836			if (context->dac_enable) {
 837				context->channels[5].output = (((int16_t)value) - 0x80) << 6;
 838				//printf("DAC Write %X(%d) @ %d\n", value, context->channels[5].output, context->current_cycle);
 839			}
 840			break;
 841		case REG_DAC_ENABLE:
 842			//printf("DAC Enable: %X\n", value);
 843			context->dac_enable = value & 0x80;
 844			break;
 845		}
 846	} else if (context->selected_reg < 0xA0) {
 847		//part
 848		uint8_t op = context->selected_part ? (NUM_OPERATORS/2) : 0;
 849		//channel in part
 850		if ((context->selected_reg & 0x3) != 0x3) {
 851			op += 4 * (context->selected_reg & 0x3) + ((context->selected_reg & 0xC) / 4);
 852			//printf("write targets operator %d (%d of channel %d)\n", op, op % 4, op / 4);
 853			ym_operator * operator = context->operators + op;
 854			switch (context->selected_reg & 0xF0)
 855			{
 856			case REG_DETUNE_MULT:
 857				operator->detune = value >> 4 & 0x7;
 858				operator->multiple = value & 0xF;
 859				break;
 860			case REG_TOTAL_LEVEL:
 861				operator->total_level = (value & 0x7F) << 5;
 862				break;
 863			case REG_ATTACK_KS:
 864				operator->key_scaling = 3 - (value >> 6);
 865				operator->rates[PHASE_ATTACK] = value & 0x1F;
 866				break;
 867			case REG_DECAY_AM:
 868				operator->am = value & 0x80;
 869				operator->rates[PHASE_DECAY] = value & 0x1F;
 870				break;
 871			case REG_SUSTAIN_RATE:
 872				operator->rates[PHASE_SUSTAIN] = value & 0x1F;
 873				break;
 874			case REG_S_LVL_R_RATE:
 875				operator->rates[PHASE_RELEASE] = (value & 0xF) << 1 | 1;
 876				operator->sustain_level = (value & 0xF0) << 3;
 877				if (operator->sustain_level == 0x780) {
 878					operator->sustain_level = MAX_ENVELOPE;
 879				}
 880				break;
 881			case REG_SSG_EG:
 882				if (!(value & SSG_ENABLE)) {
 883					value = 0;
 884				}
 885				if ((value ^ operator->ssg) & SSG_INVERT) {
 886					operator->inverted ^= SSG_INVERT;
 887				}
 888				operator->ssg = value;
 889				break;
 890			}
 891		}
 892	} else {
 893		uint8_t channel = context->selected_reg & 0x3;
 894		if (channel != 3) {
 895			if (context->selected_part) {
 896				channel += 3;
 897			}
 898			//printf("write targets channel %d\n", channel);
 899			switch (context->selected_reg & 0xFC)
 900			{
 901			case REG_FNUM_LOW:
 902				context->channels[channel].block = context->channels[channel].block_fnum_latch >> 3 & 0x7;
 903				context->channels[channel].fnum = (context->channels[channel].block_fnum_latch & 0x7) << 8 | value;
 904				context->channels[channel].keycode = context->channels[channel].block << 2 | fnum_to_keycode[context->channels[channel].fnum >> 7];
 905				break;
 906			case REG_BLOCK_FNUM_H:{
 907				context->channels[channel].block_fnum_latch = value;
 908				break;
 909			}
 910			case REG_FNUM_LOW_CH3:
 911				if (channel < 3) {
 912					context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7;
 913					context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value;
 914					context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7];
 915				}
 916				break;
 917			case REG_BLOCK_FN_CH3:
 918				if (channel < 3) {
 919					context->ch3_supp[channel].block_fnum_latch = value;
 920				}
 921				break;
 922			case REG_ALG_FEEDBACK:
 923				context->channels[channel].algorithm = value & 0x7;
 924				switch (context->channels[channel].algorithm)
 925				{
 926				case 0:
 927					//operator 3 modulated by operator 2
 928					//this uses a special op2 result reg on HW, but that reg will have the most recent
 929					//result from op2 when op3 starts executing
 930					context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output;
 931					context->operators[channel*4+1].mod_src[1] = NULL;
 932					
 933					//operator 2 modulated by operator 1
 934					context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
 935					
 936					//operator 4 modulated by operator 3
 937					context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
 938					context->operators[channel*4+3].mod_src[1] = NULL;
 939					break;
 940				case 1:
 941					//operator 3 modulated by operator 1+2
 942					//op1 starts executing before this, but due to pipeline length the most current result is
 943					//not available and instead the previous result is used
 944					context->operators[channel*4+1].mod_src[0] = &context->channels[channel].op1_old;
 945					//this uses a special op2 result reg on HW, but that reg will have the most recent
 946					//result from op2 when op3 starts executing
 947					context->operators[channel*4+1].mod_src[1] = &context->operators[channel*4+2].output;
 948					
 949					//operator 2 unmodulated
 950					context->operators[channel*4+2].mod_src[0] = NULL;
 951					
 952					//operator 4 modulated by operator 3
 953					context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
 954					context->operators[channel*4+3].mod_src[1] = NULL;
 955					break;
 956				case 2:
 957					//operator 3 modulated by operator 2
 958					//this uses a special op2 result reg on HW, but that reg will have the most recent
 959					//result from op2 when op3 starts executing
 960					context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output;
 961					context->operators[channel*4+1].mod_src[1] = NULL;
 962					
 963					//operator 2 unmodulated
 964					context->operators[channel*4+2].mod_src[0] = NULL;
 965					
 966					//operator 4 modulated by operator 1+3
 967					//this uses a special op1 result reg on HW, but that reg will have the most recent
 968					//result from op1 when op4 starts executing
 969					context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output;
 970					context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output;
 971					break;
 972				case 3:
 973					//operator 3 unmodulated
 974					context->operators[channel*4+1].mod_src[0] = NULL;
 975					context->operators[channel*4+1].mod_src[1] = NULL;
 976					
 977					//operator 2 modulated by operator 1
 978					context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
 979					
 980					//operator 4 modulated by operator 2+3
 981					//op2 starts executing before this, but due to pipeline length the most current result is
 982					//not available and instead the previous result is used
 983					context->operators[channel*4+3].mod_src[0] = &context->channels[channel].op2_old;
 984					context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output;
 985					break;
 986				case 4:
 987					//operator 3 unmodulated
 988					context->operators[channel*4+1].mod_src[0] = NULL;
 989					context->operators[channel*4+1].mod_src[1] = NULL;
 990					
 991					//operator 2 modulated by operator 1
 992					context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
 993					
 994					//operator 4 modulated by operator 3
 995					context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
 996					context->operators[channel*4+3].mod_src[1] = NULL;
 997					break;
 998				case 5:
 999					//operator 3 modulated by operator 1
1000					//op1 starts executing before this, but due to pipeline length the most current result is
1001					//not available and instead the previous result is used
1002					context->operators[channel*4+1].mod_src[0] = &context->channels[channel].op1_old;
1003					context->operators[channel*4+1].mod_src[1] = NULL;
1004					
1005					//operator 2 modulated by operator 1
1006					context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
1007					
1008					//operator 4 modulated by operator 1
1009					//this uses a special op1 result reg on HW, but that reg will have the most recent
1010					//result from op1 when op4 starts executing
1011					context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output;
1012					context->operators[channel*4+3].mod_src[1] = NULL;
1013					break;
1014				case 6:
1015					//operator 3 unmodulated
1016					context->operators[channel*4+1].mod_src[0] = NULL;
1017					context->operators[channel*4+1].mod_src[1] = NULL;
1018					
1019					//operator 2 modulated by operator 1
1020					context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
1021					
1022					//operator 4 unmodulated
1023					context->operators[channel*4+3].mod_src[0] = NULL;
1024					context->operators[channel*4+3].mod_src[1] = NULL;
1025					break;
1026				case 7:
1027					//everything is an output so no modulation (except for op 1 feedback)
1028					context->operators[channel*4+1].mod_src[0] = NULL;
1029					context->operators[channel*4+1].mod_src[1] = NULL;
1030					
1031					context->operators[channel*4+2].mod_src[0] = NULL;
1032					
1033					context->operators[channel*4+3].mod_src[0] = NULL;
1034					context->operators[channel*4+3].mod_src[1] = NULL;
1035					break;
1036				}
1037				context->channels[channel].feedback = value >> 3 & 0x7;
1038				//printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel);
1039				break;
1040			case REG_LR_AMS_PMS:
1041				context->channels[channel].pms = (value & 0x7) * 32;
1042				context->channels[channel].ams = value >> 4 & 0x3;
1043				context->channels[channel].lr = value & 0xC0;
1044				//printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel);
1045				break;
1046			}
1047		}
1048	}
1049
1050	context->write_cycle = context->current_cycle;
1051	context->busy_cycles = context->selected_reg < 0xA0 ? BUSY_CYCLES_DATA_LOW : BUSY_CYCLES_DATA_HIGH;
1052	context->status |= 0x80;
1053}
1054
1055uint8_t ym_read_status(ym2612_context * context)
1056{
1057	return context->status;
1058}
1059
1060void ym_print_channel_info(ym2612_context *context, int channel)
1061{
1062	ym_channel *chan = context->channels + channel;
1063	printf("\n***Channel %d***\n"
1064	       "Algorithm: %d\n"
1065		   "Feedback:  %d\n"
1066		   "Pan:       %s\n"
1067		   "AMS:       %d\n"
1068		   "PMS:       %d\n",
1069		   channel+1, chan->algorithm, chan->feedback,
1070		   chan->lr == 0xC0 ? "LR" : chan->lr == 0x80 ? "L" : chan->lr == 0x40 ? "R" : "",
1071		   chan->ams, chan->pms);
1072	if (channel == 2) {
1073		printf(
1074		   "Mode:      %X: %s\n",
1075		   context->ch3_mode, context->ch3_mode ? "special" : "normal");
1076	}
1077	for (int operator = channel * 4; operator < channel * 4+4; operator++)
1078	{
1079		int dispnum = operator - channel * 4 + 1;
1080		if (dispnum == 2) {
1081			dispnum = 3;
1082		} else if (dispnum == 3) {
1083			dispnum = 2;
1084		}
1085		ym_operator *op = context->operators + operator;
1086		printf("\nOperator %d:\n"
1087		       "    Multiple:      %d\n"
1088			   "    Detune:        %d\n"
1089			   "    Total Level:   %d\n"
1090			   "    Attack Rate:   %d\n"
1091			   "    Key Scaling:   %d\n"
1092			   "    Decay Rate:    %d\n"
1093			   "    Sustain Level: %d\n"
1094			   "    Sustain Rate:  %d\n"
1095			   "    Release Rate:  %d\n"
1096			   "    Amplitude Modulation %s\n",
1097			   dispnum, op->multiple, op->detune, op->total_level,
1098			   op->rates[PHASE_ATTACK], op->key_scaling, op->rates[PHASE_DECAY],
1099			   op->sustain_level, op->rates[PHASE_SUSTAIN], op->rates[PHASE_RELEASE],
1100			   op->am ? "On" : "Off");
1101	}
1102}
1103
1104void ym_print_timer_info(ym2612_context *context)
1105{
1106	printf("***Timer A***\n"
1107	       "Current Value: %d\n"
1108		   "Load Value:    %d\n"
1109		   "Triggered:     %s\n"
1110		   "Enabled:       %s\n\n",
1111		   context->timer_a,
1112		   context->timer_a_load,
1113		   context->status & BIT_STATUS_TIMERA ? "yes" : "no",
1114		   context->timer_control & BIT_TIMERA_ENABLE ? "yes" : "no");
1115	printf("***Timer B***\n"
1116	       "Current Value: %d\n"
1117		   "Load Value:    %d\n"
1118		   "Triggered:     %s\n"
1119		   "Enabled:       %s\n\n",
1120		   context->timer_b,
1121		   context->timer_b_load,
1122		   context->status & BIT_STATUS_TIMERB ? "yes" : "no",
1123		   context->timer_control & BIT_TIMERB_ENABLE ? "yes" : "no");
1124}
1125
1126void ym_serialize(ym2612_context *context, serialize_buffer *buf)
1127{
1128	save_buffer8(buf, context->part1_regs, YM_PART1_REGS);
1129	save_buffer8(buf, context->part2_regs, YM_PART2_REGS);
1130	for (int i = 0; i < NUM_OPERATORS; i++)
1131	{
1132		save_int32(buf, context->operators[i].phase_counter);
1133		save_int16(buf, context->operators[i].envelope);
1134		save_int16(buf, context->operators[i].output);
1135		save_int8(buf, context->operators[i].env_phase);
1136		save_int8(buf, context->operators[i].inverted);
1137	}
1138	for (int i = 0; i < NUM_CHANNELS; i++)
1139	{
1140		save_int16(buf, context->channels[i].output);
1141		save_int16(buf, context->channels[i].op1_old);
1142		//Due to the latching behavior, these need to be saved
1143		//even though duplicate info is probably in the regs array
1144		save_int8(buf, context->channels[i].block);
1145		save_int16(buf, context->channels[i].fnum);
1146		save_int8(buf, context->channels[i].keyon);
1147	}
1148	for (int i = 0; i < 3; i++)
1149	{
1150		//Due to the latching behavior, these need to be saved
1151		//even though duplicate info is probably in the regs array
1152		save_int8(buf, context->ch3_supp[i].block);
1153		save_int8(buf, context->ch3_supp[i].fnum);
1154	}
1155	save_int8(buf, context->timer_control);
1156	save_int16(buf, context->timer_a);
1157	save_int8(buf, context->timer_b);
1158	save_int8(buf, context->sub_timer_b);
1159	save_int16(buf, context->env_counter);
1160	save_int8(buf, context->current_op);
1161	save_int8(buf, context->current_env_op);
1162	save_int8(buf, context->lfo_counter);
1163	save_int8(buf, context->csm_keyon);
1164	save_int8(buf, context->status);
1165	save_int8(buf, context->selected_reg);
1166	save_int8(buf, context->selected_part);
1167	save_int32(buf, context->current_cycle);
1168	save_int32(buf, context->write_cycle);
1169	save_int32(buf, context->busy_cycles);
1170}
1171
1172void ym_deserialize(deserialize_buffer *buf, void *vcontext)
1173{
1174	ym2612_context *context = vcontext;
1175	uint8_t temp_regs[YM_PART1_REGS];
1176	load_buffer8(buf, temp_regs, YM_PART1_REGS);
1177	context->selected_part = 0;
1178	for (int i = 0; i < YM_PART1_REGS; i++)
1179	{
1180		uint8_t reg = YM_PART1_START + i;
1181		if (reg == REG_TIME_CTRL) {
1182			context->ch3_mode = temp_regs[i] & 0xC0;
1183		} else if (reg != REG_FNUM_LOW && reg != REG_KEY_ONOFF) {
1184			context->selected_reg = reg;
1185			ym_data_write(context, temp_regs[i]);
1186		}
1187	}
1188	load_buffer8(buf, temp_regs, YM_PART2_REGS);
1189	context->selected_part = 1;
1190	for (int i = 0; i < YM_PART2_REGS; i++)
1191	{
1192		uint8_t reg = YM_PART2_START + i;
1193		if (reg != REG_FNUM_LOW) {
1194			context->selected_reg = reg;
1195			ym_data_write(context, temp_regs[i]);
1196		}
1197	}
1198	for (int i = 0; i < NUM_OPERATORS; i++)
1199	{
1200		context->operators[i].phase_counter = load_int32(buf);
1201		context->operators[i].envelope = load_int16(buf);
1202		context->operators[i].output = load_int16(buf);
1203		context->operators[i].env_phase = load_int8(buf);
1204		if (context->operators[i].env_phase > PHASE_RELEASE) {
1205			context->operators[i].env_phase = PHASE_RELEASE;
1206		}
1207		context->operators[i].inverted = load_int8(buf) != 0 ? SSG_INVERT : 0;
1208	}
1209	for (int i = 0; i < NUM_CHANNELS; i++)
1210	{
1211		context->channels[i].output = load_int16(buf);
1212		context->channels[i].op1_old = load_int16(buf);
1213		context->channels[i].block = load_int8(buf);
1214		context->channels[i].fnum = load_int16(buf);
1215		context->channels[i].keycode = context->channels[i].block << 2 | fnum_to_keycode[context->channels[i].fnum >> 7];
1216		context->channels[i].keyon = load_int8(buf);
1217	}
1218	for (int i = 0; i < 3; i++)
1219	{
1220		context->ch3_supp[i].block = load_int8(buf);
1221		context->ch3_supp[i].fnum = load_int8(buf);
1222		context->ch3_supp[i].keycode = context->ch3_supp[i].block << 2 | fnum_to_keycode[context->ch3_supp[i].fnum >> 7];
1223	}
1224	context->timer_control = load_int8(buf);
1225	context->timer_a = load_int16(buf);
1226	context->timer_b = load_int8(buf);
1227	context->sub_timer_b = load_int8(buf);
1228	context->env_counter = load_int16(buf);
1229	context->current_op = load_int8(buf);
1230	if (context->current_op >= NUM_OPERATORS) {
1231		context->current_op = 0;
1232	}
1233	context->current_env_op = load_int8(buf);
1234	if (context->current_env_op >= NUM_OPERATORS) {
1235		context->current_env_op = 0;
1236	}
1237	context->lfo_counter = load_int8(buf);
1238	context->csm_keyon = load_int8(buf);
1239	context->status = load_int8(buf);
1240	context->selected_reg = load_int8(buf);
1241	context->selected_part = load_int8(buf);
1242	context->current_cycle = load_int32(buf);
1243	context->write_cycle = load_int32(buf);
1244	context->busy_cycles = load_int32(buf);
1245}