CPU実験室

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

シリアルテスト

シリアルコントローラからインクリメントデータを垂れ流すプログラムを書いてみました。一気に本格的なコーディングのようですが中身はコントローラの初期化追加とLチカループに1文字送信ルーチンを挿入しただけです

f:id:O3I:20200113172515j:plain

このプログラムで重要なのはシリアルコントローラのテストというより、サブルーチンの動作確認です。1文字送信と1文字受信処理をサブルーチンで記述してあり、プログラムの最初にスタックポインタをSRAMの底付近0xFFFF00に初期化した後、ループの中で1文字送信ルーチンTXをコールしています。

 

プログラムをROMに焼いて実行、シリアル出力を38400bps設定のターミナルプログラムで受けると一発でうまくいきました。

f:id:O3I:20200113160034j:plain

このプログラムが動作しているというのは、サブルーチンが正常にコールされリタンしている、つまりスタックも動いているわけでまだ未確認のSRAMも間接的に動作確認できたということになります。

シリアルのDsubコネクタの周りの眩しいLEDはTL16C550が出力する送受信RX・TX、モデム制御/DTR、汎用出力OUT1,OUT2信号のレベルを示していますがちょっと明るすぎでした。/DTRとOUT1,2はプログラムから消灯することが可能です

f:id:O3I:20200113155826j:plain

 

動作は一度でうまくいきましたが実はコーディングしているときかなり悩みました。ニーモニックが多少違うくらいで流れはどのCPUでも変わらない単純なプログラムなのですが、なかなかエラーが消えません。RXが定義されていない、というわけがわからないエラーなのですが発生しているソース行がわかりません

f:id:O3I:20200113161521j:plain

 

1行づつソースをコメントアウトしながらバグを探すと問題はサブルーチンの最後にあるリタン命令RETでした。初めは他のCPUと同じように「RET」だけコーディングしていたのですが、NS32000シリーズではRETに必ず引数が必要で省略できないようです

f:id:O3I:20200113162614j:plain

結局「RET 0」のコーディングで通りましたが、省略してしまうとアセンブラは改行を無視して次の有効なトークンを探しに行くので他の行でわけのわからないエラーになったってことでした。

RETの引数はサブルーチンをコールするときスタックにサブルーチンへ渡す値を積んだ場合、リタン時にスタックポインタを補正するための値ということですが、これは実はx86系CPUのインストラクションにもありました。ただx86ではこれは省略可でアセンブリ言語で直書きするときに使ったことはありません。Cコンパイラが出力するコードでは多用されるのかもしれません