/*	
 *	framym.c
 *
 *	P/ECE YM (ST-Sound) Driver
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2004 Naoyuki Sawa
 *
 *	* Mon Apr 19 19:00:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 */
#include "clip.h"

/****************************************************************************
 *	YMドライバ内部関数
 ****************************************************************************/

int
ym_mix(YMDRIVER* ym, short wbuff[/*YMBUFLEN*/])
{
	YMINFO* info = &ym->info;
	AY38910* ay38910 = &ym->ay38910;
	//
	int cnt1 = YMBUFLEN;	/* 残りサンプル数 */
	int cnt2;
	//
	const unsigned char* p;
	int i, v;

	do {
		/* (残りサンプル数)または(次回VBL発生までの残りサンプル数)の少ない方を取得。 */
		cnt2 = cnt1 < ym->vbl_progress ? cnt1 : ym->vbl_progress;

		/* ミキシング。 */
		if(cnt2) {
			ay38910_mix(ay38910, wbuff, cnt2);
			wbuff += cnt2;
			cnt1 -= cnt2;
			ym->vbl_progress -= cnt2;
		}

		/* VBL発生? */
		if(!ym->vbl_progress) {
			/* ループ? */
			if(ym->vbl_position >= info->nb_of_valid_vbl_of_the_file) {
				ym->vbl_position = info->vbl_number_to_loop_the_song;
				if(ym->vbl_position >= info->nb_of_valid_vbl_of_the_file) return -1; /* ループ位置不正 */
			}

			/* レジスタ更新。 */
			p = info->all_ym2149_registers;
			p += info->vbl_stride * ym->vbl_position;
			for(i = 0; i < 14/*R0〜R13のみ出力。R14〜R15は出力不要*/; i++) {
				v = *p;
				if(i == 13 && v == 0xff) {
					/* R13<=0xFFは出力なしを意味する。 */
				} else {
					ay38910_address(ay38910, i);
					ay38910_write(ay38910, (unsigned char)v);
				}
				p += info->register_stride;
			}

			/* 次回のVBL位置を更新。 */
			ym->vbl_position++;

			/* 次回VBL発生までの残りサンプル数を更新。 */
			ym->vbl_progress = ym->vbl_interval.u;
			ym->vbl_interval.d += ym->vbl_interval.n;
			if(ym->vbl_interval.d >= 0) {
				ym->vbl_interval.d -= info->player_frequency_in_hz;
				ym->vbl_progress++;
			}
		}
	} while(cnt1);

	return 0;
}

