TOP > 技術コラム(1)
 
技術コラム(1) RAMなしマイコン基板
 
拡大表示 @ 概要

左の回路図は十数年前に開発した音声基板(スピーチボード)です。
トラックに搭載して、「バックします、ご注意ください」 など数種類の音声を発生します。

このマイコン基板には何とRAMがありません。プロセッサにはもちろん内蔵RAMなど無い当時のスタンダード8bitCPUであるZ80を使い、 OKIのADPCM音声LSIであるMSM6585によって音声を再生しています。
製造原価を少しでも安くせよ、との社長命により デッドストックのロジックICを使い、アドレスデコードにも工夫を凝らしています。

RAMが無いため、ソフト製作にはさまざまな制約が生じます。
最大の障害は、スタックが使えないためcallやretによるサブルーチンが使えないことです。 割込みの受付は可能ですが、やはりretiでリターンすることはできません。

要求される動作は案外複雑で、ポート入力のうちトラックのウインカーに接続される信号は断続入力となりますが、 断続の終了を検出して音声を止める、などの処理をしなければなりません。
音声データは16kHzサンプリングレートに同期してよどみなく転送する必要があり、その裏で入力監視を行わなければなりません。

いったい、ソフトをどう組めばよいのでしょうか?
 
A ハードウェア

ハードの設計方針はいうまでも無くシンプル&ローコストです。ハードをシンプルにするためにいくつかの工夫をしています。

NMIの活用 音声の同期転送にNMIを利用しています。音声LSIが出す16kHzのクロックを2分周してNMI信号とします。 INTでも同じことができそうですが、Z80のINTはレベル入力のためソフトでレベルを戻す操作が必要になります。NMIはエッジ入力のためそのようなACK処理は不要です。 74HC74の半分を使ってリセット直後はNMIをCPUに入れないようにしています。
アドレス変換 Z80のアドレス空間は64KBですが、256KBのROMをアクセスするためにバンクに分割します。 0000H〜7FFFHはプログラム領域とし、このアドレス範囲はROM先頭のバンクにマッピングしています。 その他74HC175のD入力はデータバスでなくアドレスバスに接続してあり、74HC573への書込みと同時にバンクアドレスも設定されるようになっています。

B ソフトウェア(概要)

RAMを持たないため、変数や状態はすべてCPUのレジスタに保持しなければなりません。幸いZ80は8bitCPUにしては多くのレジスタを持っています。
AF,BC,DE,HLレジスタには裏レジスタというものがあり、IX,IYやSP,Iまで入れれば合計184bit分の状態を保持できます。
レジスタは以下のように割り当てます。

表AF汎用ワーク
表BCBは汎用、Cは音声状態(単語再生中、ポーズ中、アイドルなど)
表DEDは音声リピート制御、Eは外部入力状態
表HLサブプロシージャ(中間言語)へのポインタ
裏AF未使用
裏BCADPCM音声データブロックの長さ
裏DEDはバンクアドレス、Eは終了フラグ
裏HLADPCM音声データへのポインタ
IX入力ビットマスクテーブルへのポインタ
IYNMI音声処理後の分岐先アドレス
SPADPCM音声データブロック情報テーブルへのポインタ
I入力の有効/無効フラグ

ソースプログラムは次の通りです。→ hl400src.txt

コメントがほとんど入っていないので読みにくいと思いますが、次のような流れになっています。

・リセット後は初期化処理を行った後、NMIを禁止している74HC74をクリアしてHALTし、NMIを待つ
・NMIでは音声LSIへのデータ転送を行った後、IYの指しているサブルーチン?へ分岐し必要な処理をする
・サブルーチンはNMIを受けるごとに1ステップずつ実行し、step0〜stepfの全16ステップでループを形成している

NMIは125μs毎に発生するので5MHzクロックでは625サイクルとなり、各処理はこれを超えないよう短くしなければなりません。

C ソフトウェア(音声)

音声単語のADPCMデータを転送するための情報は以下のように6バイト単位にまとめます。この情報はPC上の音声リンカで作られます。
単語再生開始時にZ80はこれをPOP命令でレジスタにロードするだけです。

裏DEDはバンクアドレス、Eは終了フラグ
裏BC音声データブロック長さ
裏HL音声データへのポインタ

ADPCM音声データの転送はNMI処理中の ldi コマンド1行で行っています。
このコマンドは(HL)→(DE)の転送とBC--をまとめて行ってくれますのでCPUサイクルの節約になります。
本来DEには転送先を入れておかなければなりませんが、回路図からわかるようにA15==1の場合はどこに書き込んでもIC8の音声データレジスタに書き込まれます。
同時にIC5のバンクレジスタにA8-A11の値(裏DレジスタのD0-D3)が書き込まれ、これもCPUサイクルの節約に貢献しています。
A15==1の条件を付けているのは、NMIが掛かったときの自動レジスタ退避動作と区別するためです(SPのD15は常に0で使用)。
音声単語の再生を開始するのはソース中のラベルstepa:の部分で、裏HL,DE,BCに値をセットして表C=FPLYとすれば単語再生開始です。
音声転送中に裏BC==0になるとupdateラベルへ分岐して次の音声ブロックデータをPOPしますが、このとき裏EレジスタのD7==1なら単語波形の終了を意味します。
表Cは音声状態を表し、以下の3つの値を取ります。

FPLY (=FEh)音声単語再生中
FPSE (=80h)音声単語間の無音(PAUSE)再生中
FNXT (=2)音声停止中

これらは dec c を実行した後のフラグによって判別し易い値になっています。例えばFPSE (=80h)は dec c 実行後Pフラグで判別できます。
また、表CのD0はサイクル数調整bitとして使用し、1ループが常に16ステップになるようにしています。

D ソフトウェア(入力監視とシーケンス制御)

音声転送処理が終わると(IY)へジャンプして入力監視とシーケンス制御を行います。
おおまかに、ソース中のラベルstep2〜step5が入力監視、step6〜step9で入力に応じたプログラムを起動、 stepa〜stepfがプログラム中のコマンド解釈と実行部分です。
ここでいうプログラムはソース後半のPROG0〜PROG6にある一種の中間言語で、stepa〜stepfがそのインタープリタということになります。
表HLは中間言語の一要素を指すポインタとして使用しています。

step0PAUSE再生中のLength更新
step1タイミング調整用ダミーサイクル
step2入力ポートを読んで前回の値と比較
step3特別な入力ビット操作
step4入力立ち下がり判定、立ち下りならダミープログラムPROG0を実行
step5入力立ち上がり判定、判定に応じて表Bレジスタをセット
step6プログラム実行(b&1またはb&2が非0の場合)
step7プログラム実行(b&4またはb&8が非0の場合)
step8プログラム実行(b&10hまたはb&20hが非0の場合)
step9プログラム実行(ダミー)
stepaコマンド解釈:(HL)==0なら音声単語再生開始
stepbコマンド解釈:(HL)==1なら無音(ポーズ)再生開始
stepcコマンド解釈:(HL)==2なら音声パラメータへのポインタをSPに設定
stepdコマンド解釈:(HL)==3なら絶対JUMP(HLをロード)
stepeコマンド解釈:(HL)==4ならADPCM LSIのリセット等の制御
stepfコマンド解釈:(HL)==7なら入力監視によるトラップ条件設定(IXをロード)

IXは入力監視条件を決める3バイトの定数(MASKI,MASKN,MASK1〜6)へのポインタです。
入力とMASKxの1バイト目のANDを取って非0であり、その状態が50回(100ms)継続していれば監視しているビットの立ち上がりと判定します。
入力とMASKxの2バイト目のANDを取って0であり、その状態が3バイト目で示す回数(100/508ms)継続していれば立ち下がりと判定します。
前述のウインカーの断続信号が終了したことを検出するため、立ち下がり判定は約0.5秒以上継続することを条件としています。
立ち上がり判定に引っかかると、step6〜step9で表HLがセットされPROG1〜PROG6が起動されます。
立ち下がり判定に引っかかると、step4で表HLがセットされPROG0が起動され、音声が停止します。
PROG起動と同時にIXもセットされ、実行されるプログラムに応じた入力監視条件がセットされます。
こうした中間言語の導入により、音声メッセージや入力や優先度を自由に設定することができ、動作仕様変更への対応も容易になります。

E まとめ

一見奇異なRAMなしマイコン基板ですが、スピーチボード程度の機能は実装できるということがわかります。
ソフトの負担が大きくなるため、同一仕様で50枚とか100枚単位で売れる案件でないとソフト開発コストを回収できないのが難点ではあります。
ちなみにこの基板は累計500枚程度は売れ、開発コストは無事回収できました。(笑)
NMIによる強制割込みを使用しているために、CPUは何があっても暴走することがありません。
いったんソフトができてしまうと、非常に堅牢なシステムになることが実感されました。
RAMとその周辺の回路を削っても製造コストは数%程度しか下がりませんが、部品点数が減るぶん信頼性が向上します。
数値を提示できないのが残念ですが、故障や初期不良の頻度は明らかに下がりました。
その後、同じようなRAMなしスピーチボードを数機種開発しましたが、RAM内蔵CPUが安価に入手できるようになり、この方式は使命を終えました。
おわり