CPU実験室

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

メモリチェック

パラレルI/Oが動いたので次はSRAMのチェックを行います。LEDチカチカプログラムを発展させて以下のコードになりました。

ボード上のSRAMはアドレス0xFFE00000~0xFFFFFFFFでサイズ0x200000(2Mbyte)を実装しています。このプログラムはGR64をポインタとして指し示すアドレスに0x55,0xAAのチェッカコードを書き込みベリファイチェックするという動作を行います。

f:id:O3I:20201125195300j:plain

アドレスインクリメント中はA23-A16をPBポートへA15-A8をPCポートに出力してLEDをチカチカさせ進捗を示します。途中でベリファイ異常になるか、全アドレス正常でポインタが1周、オーバーフローして0x00000000に戻るとそこはROMなので必ず異常になってerror処理に飛び、0x11のマークをPAに出力します。

29kのプログラムで初めて意味のあるプログラムを頑張って書いたのですが、これがどうも案の定というかうまくいきません。アドレスはインクリメントせずLEDはSRAMのスタートアドレスを示したままピクリとも動かず、かといってエラー処理に飛んでいるわけでもなし。

もう怪しいところはどんどん削っていきます。今回の目的のメモリチェック処理をごっそり取るとこれはもう確認済Lチカループの16ビット版にすぎません。(赤枠部分)

f:id:O3I:20201125195315j:plain

ところがこれでもLEDはチカチカしないのです。これで半日悩みました。

 

原因は突然ひらめきました。ループのための無条件ジャンプの次にある命令、エラー処理の先頭のコードです。

f:id:O3I:20201125202937j:plain

ここではGR64に0x11を代入していますが

その前に無条件ジャンプがあるので実行されないはずが、実は実行されているのです

これこそが遅延分岐という奴です。もしかしたらジャンプしないとき用に「見込み」で次の命令も実行しておく、というわけですが必ず分岐する無条件ジャンプの時も行われてしまうのは意外でした。

今回の場合はループの中でGR64を一生懸命インクリメントしようとしても、毎回GR64が0x11で初期化されるのでちっとも進まないというオチでした。