CPU実験室

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

アセンブラI/F

PXレジスタを経由したポート出力はできましたが、今度はポート入力を考えてみます。やはりPXレジスタを読むアセンブラコードを書かなければなりませんがasm()文では引数でそのあたりの制御ができるようです。

f:id:O3I:20210721091114j:plain

 

ここでは以下のように記述しました。”=a”はAX系レジスタを経由してCの変数resultに代入することを指定します。

asm("%0=px;":"=a"(result));

 

これを使ってLCDの制御関数を記述してみました。データレジスタに出力するlcd_dat()はLEDのポートに出力する関数と同じ作りです。その中でLCDのステータスレジスタを読んでBUSYフラグが落ちるのを待つlcd_wait()でPXレジスタの読み取りをやっています。

f:id:O3I:20210721091209j:plain

 

このlcd_wait()ルーチンが最初はうまく動作せずちょっと悩みました。BUSYフラグを全くチェックせずに即時リタンしてしまうので初期化がうまくいかなかったり文字列が歯抜けして表示したりしたのですが、これはCの変数dumy,resultC言語自体のルーチンの中では代入だけして参照しない、代入せずに参照するなどで最適化によって行ごと削除されてしまったためでした。つまりlcd_wait()の中身自体が何もしてないとみなされて中が空っぽになってしまいます。ここは変数dumy,resultvolatile 宣言して最適化で消されないようにします。

 

できあがったlcd_wait()コンパイルしたアセンブリ中間ファイルはこのような感じです。関数の入口・出口処理:FUNCTION PROLOGUEFUNCTION EPILOGUEは省いていますがそれでもかなり迂遠なコードを出力しています。80系のアセンブラ直書きなら2~3行で済んでしまうところですが、そもそもDSPにトロトロ遅いヒューマンI/Fを処理させていること自体かわいそうなのかもしれません。

 

f:id:O3I:20210721093342j:plain