CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

プロジェクト完了

CPU内モジュールのすべての機能を確認したわけではないですが、おそらく動作するであろうということでボードとしての開発は完了。応用は別途考えます。

 

汎用的に使えるように技術資料はぼちぼち整備しておきましょう。部配図とパタンとか

 

コネクタのピンアサインやジャンパポストの機能図もまじめに作りました

 

組込みモジュールとして小さくまとまりました。大きさも市販の某シングルボードコンピュータとなんの遜色もありません。(いや性能は雲泥の差ですが・・・)

 

Cコーディング

CC900コンパイラに付属している標準ライブラリには文字列処理is~、str~、mem~、printf系関数やsin/cosなど数学関数、malloc/freeといったヒープ操作も含まれているのであとはハードウェアに依存した入出力関数などをちょこちょこっと作ってやればそれで全てです。

いままで他のボードにも作ってきたような1文字出力putcom、1文字入力getcom、文字列出力putstrといったもので、見るステータスが違うくらいでほとんどコピペで持ってこれます

ただちょっと嵌まったのが1文字出力putcomでした。定石通り送信バッファエンプティをみて送信バッファに送信文字をセットするという動作をしているだけです。ただステータスがハードウェアのステータスレジスタを読んでいるのではなく送信割込みでセットされるメモリ上のフラグを読んでいるということと、フラグをクリアするのもソフトでやっている、という違いはあります

ところがこの関数はポツンポツンと呼ぶ分には正常動作しますが文字列出力などで連続コールするとふん詰まり状態になって全く文字を送信してくれません、割込みによるタイムラグかとおもい処理の順番を変えたりしたのですがうまくいかず結局コマンド間にウェイトを置く(赤枠部分のwait(200))で成功しています。wait(200)は実測270usかかっていて38400baudで1文字10bit送信に要する時間1/38400*10=260usとほぼ同じです。このため送信に時間ロスが発生することはありません。でもそれなら送信バッファ空TXEMPTYのチェックも不要になるわけで何か気になりますが一応これで動作はするのでとりあえずOKとしておきます。

 

CC900コンパイラはもちろん浮動小数点演算もサポートしているでまたまたマンデルブロ集合を描かせてみました。TLCS900/H1浮動小数アクセラレータを内蔵しているわけではないのでソフト処理による力技でそれほど速くはありません。高解像度はやめておいてキャラクタベースの80×40メッシュでやってみます。

 

生成されたバイナリは2474byte、描画時間は20秒でした

 

いま、ボード上には20MHzの水晶が付いていますがこれを10MHzに付け替えてクロックギアでPLL4逓倍に切り替えれば2倍速になるかもです

CでLチカ

環境が整ったのでCでプログラムしてみます

まずはソースファイル。内蔵パラレルポートP7を定義するためにヘッダファイルio900h1.hをインクルードしていますが、

ソース本体はアセンブラ言語でのLチカテストとほぼ同じになっています

ソースファイル:TEST.C

コンパイル時のコマンドライン

   cc900 -Nb3 -O3 -laf %1.map -o %1.abs stc92ml.rel %1.c c92.lcf
オプションは

 -Nb3:ターゲットCPUをTLCS900/H1指定

 -O3:最適化最大

 -laf fname:リスティングファイルとマップファイルを出力

 -o fname:出力ファイル指定

ソースファイル以外の入力ファイルはアセンブル済スタートアップstc92ml.relとリンケージファイルc92.lcfです

 

リスティングファイル:TEST.LST

マップファイル:TEST.MAP

ちゃんとコードは0x20000、データは0x2000から配置されました

 

リンカが出力するオブジェクトTEST.ABSIEEE695オブジェクトモジュールフォーマットで扱いにくいのでオブジェクトコンバータtuconvIntelヘキサフォーマットに変換します

   tuconv -ra 0x20000,,0 %1.hex %1.abs

さらにモニタでダウンロードするためバイナリに変換します

   hex2bin %1.hex %1.bin

ようやくターミナルからDLLできる形式になりました

 

ファイルカスタマイズ

Cで書いたプログラムはそれを動作させるためにある程度のお膳立てが必要でそのためのサンプルコードが付属していました。これをそれぞれの環境に合わせてカスタマイズしろ、ということです

まず必要なのがスタートアップルーチン。スタックの設定、静的変数のクリア・初期化、最後にCプラグラムのmain()関数にジャンプするという動作です。アプリケーションはモニタから起動されモニタの環境を継承するのでスタックの設定はしなくても良いですが、ここは雛型のまま全く手を入れないで使うことにします。

大事なのはこのルーチンがアプリケーションより前、一番最初にリンクさせることで、そうしないと_startupのアドレスがユーザRAMの先頭0x20000になってくれません

 

スタートアップルーチン:stc92ml.asm

 

内蔵レジスタのアドレスを定義したファイルです。これをインクルードしておけばレジスタ名称でアクセスすることができます。直しは要りません

I/Oアドレス定義ファイル:io900h1.h

 

出来上がったオブジェクトをリンクして実アドレスへリロケートする指示ファイルです。今回ボードに拡張しているSRAMの先頭アドレス、サイズを雛型に対して追記しています EMEM1  : org=0x020000, len=0x020000

さらにセクション指示でコードエリアは外付け拡張SRAM0x20000~、データエリアはCPU内蔵SRAM0x2000~と記述しました

リンケージファイル:c92.lcf

 

Cコンパイラ

TLCS-900ボードのプログラムはアセンブリ言語でちょこっと書いてASアセンブル、実行はできていますが、ボード上のI/Oがport7のbit3につないだLED1個だけ。あまり面白い動きをさせることもできないのでちょっと放置していました。

 

アセンブラによるLチカ例。見た目ほとんどZ80のコードですがDJNZのカウンタに任意の16bitレジスタが使えるところがちょっとうれしい

T社はCコンパイラを含むTLCS-900シリーズのGUI統合開発環境TIDEを提供しているのですが、有償か無償かわからず公式サイトからダウンロードもできず、さてどうしたものかといろいろ探っていたらcc900.exeというコマンドライン版のコンパイラが見つかりました。T社純正のようですがこれも許諾関係が明らかでないのでちょっと試してみる程度にしておきます。

なにより国産品なので付属のマニュアルがすべて日本語というのが助かります。

たとえばこのような中身が空のサンプルコードtest.c

void main(void)
{
}

コマンドプロンプト内でコンパイル

>cc900 -Nb3 -l -V test.c

オプションの-Nb3はターゲットCPUをTLCS-900/H1に指定、-lはリスト出力 -Vはバージョン表示・・最初はこれくらいで十分です。

コンパイルはあっさり通り、リストファイルとリロケータブルオブジェクト、絶対バイナリファイルが生成されました

標準ライブラリも付属しているのでこれであとリロケーション指定や出力ファイル形式を指示すればボード上で動くプログラムを作れそうです

コーデックでLチカ

コーデック本来の機能であるA/D、D/A部分の確認が先にできてしまったのですがおまけ機能の汎用出力ピンでLチカも一応やっておきます

汎用出力ピンXCTL0/1の制御はインデックスアドレス#10:pin control regに割り付けられています

 

ループバックプログラムを改造して割込み待ち永久ループtalkthruのなかでレジスタAY1の上位8bitの値をパラレルLEDとコーデックのXCTLに出力します

 

割込みルーチンは他のCPUボードでのテストと同じようにレジスタをインクリメントするだけの処理にしています

 

これを実行してみました。サンプルレートは48kHzにしたのでフレーム割込みも48kHzで発生していると考えられます

よってインクリメントも48kHzでおきるので16bitの最上位D15を反映するXCTL1は48kHz/(2^16)=0.73Hz ,同様にD14のXCTL0は48kHz/(2^15)=1.46Hz のちょうどいい速度でLチカできました

AY1の上位8bitの値は同時にパラレルポートに出力しているので最下位D8をカウンタでプローブすると48kHz/(2^9)=93.75Hzが測定できています

 

 

ループバック実行

コーデックへの初期化コマンドチェインの内容はこうなっています。コントロールワードに含まれるインデックスでポイントされる13個の8ビットレジスタにデータをセットしていきます。コード上はプログラムメモリ領域に埋め込まれるので24ビット幅データですがシリアル送信レジスタは16ビット幅なので下位8ビットはダミーで切り捨てられます。

このなかで重要なのはDSPとのインターフェースを決定するinterface configurationmiscellaneous informationでこれはサンプルコードそのままにしておきました

data format registerはオーディオデータフォーマットとサンプリングレートを設定します。サンプルコードのままだとfs=8kHzですがCFS=6に設定してやるとステレオ16ビットリニアPCMfs=48kHzとCDを上回りDATに匹敵する高音質にすることができます

 

これでループバックプログラムの準備が整ったので、いよいよ実行。入力信号としてラジオの音声を入力し、出力をモニタスピーカにつないでみます

 

聴いてる感じでは音質には全く遜色なし。アナログで直結してるのと変わりません。電源系統分離の効果があったのか心配だったノイズも気になりませんでした。

ch1:入力信号、ch2:出力信号

 

ところでラジオを聴きながらCPU回路の実験をしていると、ボードが起動したとたんラジオの音声がスッと消えることがあります。いままで作成したCPUボードが原振16MHzというのが割と多く、且つ、つけていたラジオがTOKYOFM(80.0MHz)だと16MHz矩形波の奇数次高調波(5次高調波)が16×5=80でちょうど放送波と合致するのですね。それ以外の組合せでは全く問題ないのですが、基板むき出しでそうとう妨害波をまき散らしているようです