SFG-01とSFG-05で困っていること

MSXにSFG-01やSFG-05を繋いで、自作のサウンドドライバを使って曲を演奏させているのですが、挙動の違いで困っていることがあります。

SFG-01/05は資料も少なく、また、OPMについても私自身あまり明るくないので、もしご存知の方がいればぜひアドバイスをいただきたいです…。

…という質問をtwitterでつぶやいたところ

回答をいただきました!

こちらのページに書かれておりました。

http://map.grauw.nl/resources/sound/yamaha_ym2164.php

SFG-01はOPM、SFG-05はOPPが搭載されているのですが、OPPはTimerBの挙動がOPMと違っており、セットする値も変えなければならないようです。

これでスッキリしました。

次回ドライバを作るときには、正式に両対応したいと思います!

(今となっては解決済みですが…)動画

こちらの動画は、TimerA・TimerB ともにタイマー割り込みを10ms(1/100秒)に設定し、割り込み10回(1/10秒)ごとに文字を表示して、さらに10文字(1秒)ごとにキャラクターを変更して表示位置をリセットしています。

しかし、SFG-05の TimerB のみ、割り込み回数が1/2になってしまうのです…。

TimerBを使用したサウンドドライバを作りたいのですが、この挙動の違いが解決できず、困っております。

(今となっては解決済みですが…)チェッカーのソース


;==================================================
; SFG-01/SFG-05 タイマー割り込みテストプログラム
;==================================================
;------------------------------------
;SFG REGISTER
;------------------------------------
OPMSTAT		EQU	3FF1H
OPMADDR		EQU	3FF0H
OPMDATA		EQU	3FF1H
;------------------------------------
;VDP PORT
;------------------------------------
VDPPORT0	EQU	098H
VDPPORT1	EQU	099H
;------------------------------------
;情報表示用VRAMアドレス
;------------------------------------
SFGVRAM		EQU	1806H
TMAVRAM		EQU	1900H
TMBVRAM		EQU	1A00H
;------------------------------------
;ワークエリア
;------------------------------------
WORK		EQU	0C800H
WORKTMA		EQU	WORK
WORKTMB		EQU	WORK+4
;------------------------------------
;SFGスロット
;------------------------------------
SFGSLTBS	EQU	2	;SFGの基本スロットを書く
SFGSLTEX	EQU	0	;SFGの拡張スロットを書く
;------------------------------------
;TIMER A
;------------------------------------
;Taを割り込み時間(msec)とすると以下の式で計算できる
;CLKA = 1024 - Ta * 3579.545 / 64
;10msec(1/100sec)の場合 CLKA = 465 = 01D1H
CLKA		EQU	01D1H		;全10ビット
CLKAH		EQU	(CLKA/4)	;上位8ビット
CLKAL		EQU	CLKA-(CLKAH*4)	;下位2ビット
;------------------------------------
;TIMER B
;------------------------------------
;Tbを割り込み時間(msec)とすると以下の式で計算できる
;CLKB = 256 - Tb * 3579.545 / 1024
;10msec(1/100sec)の場合 CLKB = 221 = 00DDH
CLKB		EQU	00DDH		;全8ビット
;------------------------------------

HEADER:
	DB	0FEH
	DW	PRGSTART
	DW	PRGEND-1
	DW	PRGSTART

	ORG	0A000H
	
PRGSTART:
	LD	A,1
	CALL	005FH	;CHGMOD スクリーン1に変更
	
	LD	HL,TXTSFG
	LD	DE,SFGVRAM
	LD	BC,20
	CALL	005CH	;LDIRVM
	;SFGのバージョンを調べる
	LD	A,SFGSLTBS+SFGSLTEX*4+80H	;スロット番号
	LD	HL,0073H
	CALL	000CH	;RDSLT
	;SFG-01: "1983 by YAMAHA"
	;SFG-05: "1984 by YAMAHA"
	;            ^ ここの文字をチェック(0073H)
	CP	'3'
	JR	Z,SFG01
	CP	'4'
	JR	Z,SFG05
	RET
SFG01:
	LD	HL,TXTSFG01
	JR	SFGINFO
SFG05:
	LD	HL,TXTSFG05
SFGINFO:
	LD	DE,SFGVRAM+13
	LD	BC,7
	CALL	005CH	;LDIRVM
	LD	HL,TXTTMRA
	LD	DE,TMAVRAM+12
	LD	BC,6
	CALL	005CH	;LDIRVM
	LD	HL,TXTTMRB
	LD	DE,TMBVRAM+12
	LD	BC,6
	CALL	005CH	;LDIRVM

	DI
	
	;SFGを表に出す
	CALL	CHGSLOT

	;ワークエリア初期化
	LD	HL,WORKINI
	LD	DE,WORK
	LD	BC,8
	LDIR
	;TimerA 割り込みセット
	LD	D,10H		;レジスタ10H
	LD	E,CLKAH
	CALL	OUTSFG
	LD	D,11H		;レジスタ11H
	LD	E,CLKAL
	CALL	OUTSFG
	;TimerB 割り込みセット
	LD	D,12H		;レジスタ12H
	LD	E,CLKB
	CALL	OUTSFG
	;割り込み開始
	LD	D,14H		;レジスタ14H
	;---------------------------------------------------------------
	;bit7	bit6	bit5	bit4	bit3	bit2	bit1	bit0
	;-	-	TmBリセ	TmAリセ	TmB許可	TmA許可	TmB開始	TmA開始
	;---------------------------------------------------------------
	LD	E,3FH		;TimerA, TimerB 両方を許可&リセット
	CALL	OUTSFG
WAIT:
	;ステータスを読む
	LD	A,(OPMSTAT)
	;---------------------------------------------------------------
	;bit7	bit6	bit5	bit4	bit3	bit2	bit1	bit0
	;BUSY	-	-	-	-	-	TimerB	TimerA
	;---------------------------------------------------------------
	BIT	7,A
	JR	NZ,WAIT		;BUSY
	;TimerA割り込みチェック
	BIT	0,A
	PUSH	AF
	CALL	NZ,TMAFUNC
	POP	AF
	;TimerB割り込みチェック
	BIT	1,A
	CALL	NZ,TMBFUNC
	JR	WAIT
;------------------------------------
;OPMレジスタ書き込み
;入力: D レジスタ
;       E データ
;------------------------------------
OUTSFG:
	LD	HL,OPMADDR
	LD	(HL),D
	LD	HL,OPMDATA
	LD	(HL),E
	RET
;------------------------------------
;TimerA割り込み時処理
;------------------------------------
TMAFUNC:
	LD	IX,WORKTMA	;TimerA用ワーク
	CALL	TMCNTUP		;カウントアップとキャラ表示処理
	LD	D,14H		;レジスタ14H
	LD	E,1FH		;TimerAのみリセット
	CALL	OUTSFG
	RET
;------------------------------------
;TimerB割り込み時処理
;------------------------------------
TMBFUNC:
	LD	IX,WORKTMB	;TimerB用ワーク
	CALL	TMCNTUP		;カウントアップとキャラ表示処理
	LD	D,14H		;レジスタ14H
	LD	E,2FH		;TimerBのみリセット
	CALL	OUTSFG
	RET
;------------------------------------
;割り込み回数をカウントする
;10回割り込みが入るごとに画面にキャラクターを表示
;100回割り込みが入ると表示位置を左端にリセット
;入力: IX ワークエリア先頭
;------------------------------------
TMCNTUP:
	LD	A,(IX+0)	;割り込み回数カウンタ
	INC	A
	CP	10
	JR	C,TMCNTUPR	;10回割り込みが入ったか
	LD	A,(IX+2)
	OUT	(VDPPORT1),A	;キャラクター表示アドレスセットL
	PUSH	AF
	LD	A,(IX+3)
	OR	40H
	OUT	(VDPPORT1),A	;キャラクター表示アドレスセットH
	LD	A,(IX+1)
	OUT	(VDPPORT0),A	;キャラクター表示
	POP	AF
	INC	A
	CP	10
	JR	C,TMCNTUPV	;キャラクターを10個表示したか
	INC	(IX+1)		;表示キャラクターを変更
	XOR	A		;表示位置を左端にリセット
TMCNTUPV:
	LD	(IX+2),A
	XOR	A		;割り込み回数カウンタをリセット
TMCNTUPR:
	LD	(IX+0),A	;割り込み回数カウンタアップデート
	RET
;------------------------------------
;PAGE0をSFGのスロットに切り替える
;------------------------------------
CHGSLOT:
	IN	A,(0A8H)
	AND	0FCH
	OR	SFGSLTBS	;PAGE0の基本スロットをSFGに切り替える
	LD	B,A
	AND	3FH
	OR	SFGSLTBS*64
	OUT	(0A8H),A	;拡張スロット切り替えのために一時的にPAGE3も切り替える
	LD	A,(0FFFFH)
	CPL
	AND	0FCH
	OR	SFGSLTEX	
	LD	(0FFFFH),A	;拡張スロットをSFGのスロットに切り替える
	LD	A,B
	OUT	(0A8H),A	;PAGE3は戻す
	RET
;------------------------------------
;ワークエリア初期値
;------------------------------------
WORKINI:
	;Timer A
	DB	0	;TimerAの割り込みが入るとカウントアップ
	DB	0	;TimerAチェック用に表示するキャラクター
	DW	TMAVRAM	;TimerAチェック用キャラを表示するアドレス
	;Timer B
	DB	0	;TimerBの割り込みが入るとカウントアップ
	DB	0	;TimerBチェック用に表示するキャラクター
	DW	TMBVRAM	;TimerBチェック用キャラを表示するアドレス
;------------------------------------
;テキスト
;------------------------------------
TXTSFG:
	DB	'This slot is not SFG'
TXTSFG01:
	DB	'SFG-01 '
TXTSFG05:
	DB	'SFG-05 '
TXTTMRA:
	DB	'TimerA'
TXTTMRB:
	DB	'TimerB'
;------------------------------------
PRGEND:
;------------------------------------

	END

(未解決)実機とエミュレーターの挙動の違い

blueMSX、openMSXともに、Timer割り込みのタイミングが遅く、TimerA、TimerBを使っているドライバーは演奏速度が1/2になってしまいます。

いつか修正されることを期待しています。


戻る