Future Driver

PCM(YM2612)

概要

メガドライブには、スーパーファミコンやネオジオ等の様なPCM専用のRAMは無く、 CPUからダイレクトにDACへPCMデータをストリーミングする必要があります。
この為、安定した高サンプリングレート再生を実現するには、 一般的にはZ80をPCM再生の為だけに使い、 その他の全ての処理は68000を使います。

またPCMの出力方法としては通常YM2612のDACを利用しますが、 その場合はFM音源の同時発音数が1音減るので、 YM2612のDACを使用せず、PSG音源を代用する事でFM音源の発音数を減らさずに済ませるソフトが存在します。
但しPSG音源を使った場合、PSG音源1chのみでは4bitの制度しか無いので、 綺麗な音を出すには3ch同時発音させる等して精度を高める必要があります。

YM2612のDACを利用したPCM

YM2612のDACを使うには、まずYM2612のレジスタ 0x2B にデータ 0x80 を書き込んでDACを有効にします。
このDACはFM音源6ch目の為のDACを流用しているので、 FM音源の6ch目が無効になります。
以降は望みのサンプリングレートになる様に一定周期でYM2612のレジスタ 0x2A にPCMデータを書き込む事でPCM再生となります。

Z80 PCMドライバの例

;---------------------------------------------------------------------
;SOUND DRIVER (C) Minami Youichi 09.23.2008 - 10.04.2008
;
;使う人居るか知らんけど、このサウンドドライバの使い方:
;	このコードを 0xA00000(Z80のRAMエリア)に転送したら、
;	あとは鳴らしたい時に以下のシーケンスを実行すればOK。
;
;	1. 0xA00010 にPCMスタートアドレスをぶち込む
;	2. 0xA00014 にPCMエンドアドレスをぶち込む
;	3. 0xA00015 に 0x00 をぶち込む
;
;	スタートアドレスとエンドアドレスがバンクを跨いでいると死ぬ。
;	なのでバンク(32KBytes単位)を跨がない範囲に揃える必要がある。
;
;	PCMのフォーマットはYM2151のDACデータそのまんま。
;
;アセンブルの仕方:
;	Zilogスタンダードな書き方したつもり。
;	ZASMとかアブソリュートアセンブラでHEXファイル吐かせたら、
;	HEX2BINとかでバイナリ作れば良い。
;
;---------------------------------------------------------------------
A_SP:	EQU	2000h
BANK:	EQU	6000h
YM_REG:	EQU	4000h
YM_DAT:	EQU	4001h
;---------------------------------------------------------------------
	ORG	0000h
	DI			;割り込み禁止
	LD	SP, A_SP	;スタックポインタ初期化
	IM	1		;割り込みMODE 1
	JP	INIT		;RESET
;---------------------------------------------------------------------
	ORG	0010h
NOW1:	DEFW	0000h		;PCMデータの終端位置
	DEFW	0000h
END1:	DEFW	0000h		;現在のPCMデータ読み出し位置
	DEFW	0000h
PLAY1:	DEFB	00h		;1=Set Start
;---------------------------------------------------------------------
	ORG	0038h
VSYNC:	RETI			;VSYNC割り込み
;---------------------------------------------------------------------
	ORG	0040h
INIT:	NOP
SET1:	LD	HL, BANK	;バンクセレクト
	LD	A, (NOW1+1)
	RLCA
	LD	(HL), A		; bit 15
	LD	A, (NOW1+2)	;
	LD	(HL), A		; bit 16
	RRA
	LD	(HL), A		; bit 17
	RRA
	LD	(HL), A		; bit 18
	RRA
	LD	(HL), A		; bit 19
	RRA
	LD	(HL), A		; bit 20
	RRA
	LD	(HL), A		; bit 21
	XOR	A		; 32Mカートリッジまでなら上位2bitは無視可能
	LD	(HL), A		; bit 22
	LD	(HL), A		; bit 23

	LD	A, 2Bh		;FM6無効, PCM有効
	LD	(YM_REG), A
	LD	A, 80h
	LD	(YM_DAT), A

	LD	A, 2Ah		;PCMデータレジスタを選択
	LD	(YM_REG), A

	LD	A, 01h		;メインループの準備
	LD	(PLAY1), A	;再生開始フラグをクリア
	LD	BC, (NOW1)
	LD	DE, (END1)
	SET	7, B		;15bit目を1にする(ROMアドレスが32K〜63Kなので)
	SET	7, D		;15bit目を1にする(ROMアドレスが32K〜63Kなので)
	LD	HL, YM_DAT

LP1:	LD	A, (PLAY1) 	;13	メインループ
	AND	A		; 4
	JP	Z, SET1		;10	PCM1の再生開始フラグが0だったら初期化
	LD	A, B		; 4
	CP	D		; 4
	JP	Z, LP1		;10	PCMエンドアドレスに到達していたら最初に戻る
	INC	BC		; 6	ADDR_NOW++
	LD	A, (BC)		; 7	PCMデータをロード
	LD	(HL), A		; 7	YM2151のデータポートに贈る
				;計65Clock, 3579540/65= 55.070KHz  (111.86Clockで32KHz)
	NOP		  	;以下無駄命令で周波数を合わせる
	NOP
	NOP
	NOP
	NOP

	NOP
	NOP
	NOP
	NOP
	JP	LP1		;10
END	;-------------------------------------------------------------


inserted by FC2 system