2022年05月17日

SRのFM音源のタイマを使う

  FM音源(YM2203)を使用する時の話です。


  SRにはFM音源のYM2203が搭載されています。YM2203 には、一定間隔を数える、2つのタイマA/B があります。

  PC-88などでは、タイマが満了すると、割り込み信号をアクティブにして、CPUに知らせてくれるのですが、mk2SR/66SR では、この割り込み信号が接続されておらず、残念なことになっています。


  なので、タイマA/B は全く使えないと思っていたのですが、工夫次第でほぼ同程度の事ができます(既知かもしれませんが)。

  やり方は以下の通りです。


 ・ポート0xA3 を読み出す。
  このポートは、YM2203のステータスレジスタで、読み出される以下の通り。

  b7:busy時、"1"
  b1:タイマBオーバーフロー時、"1"
  b0:タイマAオーバーフロー時、"1"


  このポート0xA3 を、P6のタイマ割り込みで一定間隔で読み出せば、疑似タイマ割り込みが出来ます。



  実際のプログラムでは、以下のような実装になるかと思います。
  (タイマ割り込みなので、他のものが多いです)




;
; タイマ割り込み
; (1/1200秒割込み)
;
INTTIMER:
push af

ld a,(TIMERCNT)
inc a
and $0f
ld (TIMERCNT),a
jr nz,.next1

ld a,$06
call SETSUBCPU ; ゲームキー呼び出し

.next1:
ld a,(KEYCNT)
inc a
and $ff
ld (KEYCNT),a
jr nz,.next2
xor a
ld (KEYDATA),a ; タイマ満了時、キーバッファクリア

.next2:
;
; 1/600秒割り込み処理
;
ld a,(TIMERON)
or a
jr z,.next3

ld a,(TIMCNT600)
inc a
and $01
ld (TIMCNT600),a

call z,$8d84 ; 1/600秒割り込み

.next3:
ld a,(BGMON)
or a
jr z,.end

; YM-2203 TIMER割り込み
;
ld a,($8a14) ; 割り込みレベル
cp $05
jr c,.end

in a,($a3)
and $03
call nz,$9120 ; サウンド割り込み

.end:
pop af
ei
ret

TIMERCNT:
db $00

TIMCNT600:
db $00




  最後の方のサウンド割り込みが、それになります。
  タイマA/Bのいずれかが満了していれば、下位2ビットが00以外なので、$9120 を CALL します。

  通常、BGMを鳴らすルーチンが長いことが多いので、割り込みルーチンに入ると、フラグを立てて、割り込みを解除する事が多いです。

  上記の場合、$9120 からのルーチンでは、最初に、($8a14) に、$02 を設定して、ei をしています。
  BGMのルーチンの終了時に、($8a14) に、$05 を設定して終了しています。




posted by えすび at 15:46| Comment(0) | P6解析:音声周り | このブログの読者になる | 更新情報をチェックする

2012年11月25日

PCM再生(3)

  PCM再生(2) で使ったプログラムで再生した音声ですが、実際に録音してみました。

  音声の素材には、「あみたろの声素材工房」さんのを使用させて頂きました。

  http://www14.big.or.jp/~amiami/happy/


  声素材の中の、一番長そうなメッセージ

 「お電話ありがとうございます。大変申し訳ありませんが、本日の営業はすべて終了させていただきました。またのお電話をお待ちしております。」

 と、何となく

 「おかえりなさいませ、ご主人様」


 の2つを、8ビット11KHzサンプリングに変換して、mk2 で再生させたものが以下になります。








  ちょっと音が割れてる所がありますが、割とキレイな音声かと思います。

  ちなみに初代P6 や66 でもほとんど同じ音声です(音声関係で少〜しだけ回路が違います)。

  SR は RS232Cボードの問題により、再生できませんでした。



posted by えすび at 21:13| Comment(2) | P6解析:音声周り | このブログの読者になる | 更新情報をチェックする

PCM再生(2)

  以前作った PCM 再生プログラムでは、データのサイズが決まっていました。

  本体の RAM に格納するため、このままではどうしようもありません。


  今回は、RS-232C 経由でデータを流し込んで、PCM を再生するプログラムにしました。

pcm2.zip


  MODE1/2、PAGE1 で実行します。

  実行すると、画面が砂嵐になりますので、acknowrich などを使って、RS-232C経由で PCM データを送信します。

  PCM データは、サンプリングレート11025Hz、モノラル8ビットです。
  通信レートは 122880 bps で、ストップビット1ビット、奇数パリティにします。


  データを送信している間、そのデータを再生します。

  というか、入力されるデータをそのまま音声データに変換しているだけです(手抜き)。

  そのため、wav ファイルのヘッダなども再生されます(再生の最初にノイズとして聞こえます)。



  プログラムは簡単で、

  RS-232Cから、データが入力されるのを待つ。
  ↓
  入力されたデータをPCM データに変換して再生する。

  をひたすら繰り返しているだけです。


  そのため、ヘンな通信レートになっています。
  11025×(データ8bit+スタート1bit+ストップ1bit+パリティ1bit) = 121275

  で、これが 19.6608MHz の8分周クロックで1/16 設定 の時の 122880bps に近いので、これを使用しています。


  上記のような構成なので通信レートを遅くすると、音声がスロー再生されます。

  ちょっと笑えます(^^;


posted by えすび at 17:35| Comment(0) | P6解析:音声周り | このブログの読者になる | 更新情報をチェックする

2012年11月08日

PCM再生の追記

  PCM再生プログラムの追記です。

  使っているメモリマップは次の通りです。

  0x0000 〜 0x07FF :スクリーン1
  0x0800 〜 0x7FFF :音声データ1
  0x8000 〜 0x91FF :BASICプログラム、変数領域、スタックなど
  0x9200 〜 0xF8FF :音声データ2
  0xF900 〜 0xF9FF :ディスクなどのワークエリア
  0xFA00 〜 0xFFFF :BASICワークエリア


  MODE5、PAGE1 に設定した場合は、上記のようなメモリ配置になります。
 (0x91FF は、プログラムサイズによります)

  音声データが連続領域で取れないのですが、0x8000〜0x91FF をスキップすれば構わない事になります。


  また、アセンブラリストのPCMSTART の中で、右端に『7+1』とかコメントで書いているのは、その命令を実行するクロック数を表しています。

  +1 部分はウエイト分です。M1サイクルで+1 されます。
  ですので、普通の命令は、+1 となり、CB XX / ED XX / DD XX / FD XX などの拡張命令は、+2 になります(M1サイクルが2回あるため)。

  また、I/O 領域で、AY-3-8910 にアクセスする際は、さらに +1 されます。


  音声を出しているループの、合計クロック数が、363クロックになるようにしています。これは、4MHz で考えた時に ループの長さが 11025Hz に相当するためです。( 4MHz / 11052Hz = 362.8 )



  ところで、ある命令でクロック計算を間違えていました...

  OUT (C),B の命令ですが、12+2 になっていますが、12+3 の誤りですね。



posted by えすび at 18:17| Comment(1) | P6解析:音声周り | このブログの読者になる | 更新情報をチェックする

2012年11月07日

PCM再生

  PC-6001上のPSG(AY-3-8910)で音声を再生するプログラムを作成しました。

  既に、marknさんがニコニコ動画などでアップされているものです。MSX などでも実現されています。

  でも、まあ、試しに作ってみました。使い方の詳細も同梱しています。再生できるのは、11KHzサンプリング、8bit の WAVファイルです。

pcm.zip


  やり方がいろいろありそうですが、参考にしたのは以下のサイトです。

http://www.markn.org/blog/2008/10/psgpcm.html
http://map.grauw.nl/articles/psg_sample.php


  動作原理も書かれていますが、概略は以下の通りです。

 1)チャネルA、B、C を MIXER(レジスタ7)で オフにする。
 2)その後、チャネルA、B、C の音量を高速で変化させる。


  MIXER で、それぞれのチャネルをオフにした場合、通常は音が出ない(合成の対象にならない)ようなイメージがあります。
  しかし、実はトーンジェネレータの発振周波数を0にして、ベタHを出力するようです。

  そのため、音量を高速で変化させると、それが音となって聞こえるわけです。


  8bit のサンプリングは、1サンプル当たり 0〜255 の値があります。中心値(無音時)は、128です。このデータをチャネルA、B、C の音量に変換して、音声を再生します。

  この変換テーブルをいろいろ試したんですが、結局今回のものに落ち着きました。

  今回の変換テーブルは、音量が大きい所は同じ値になっていますので、大音量の再生には向いていません。


  WAV ファイルの読み込みには、テープと RS-232C の両方対応しました。テープはあまり実用的ではありませんが、エミュレータを使う時には有効なので。


  再生すると、エミュレータではかなりキレイな音声を再生できます。
  実機では、LPF やスピーカの関係か、ちょっとイマイチです。


  ちなみに今のPC-6001F では、上記の動作原理を再現できていないため、音声はなりません。
  そのうちに改定するつもりです。

posted by えすび at 20:38| Comment(0) | P6解析:音声周り | このブログの読者になる | 更新情報をチェックする