CPU実験室

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

Tipsつづき(2)

プログラムメモリの内容をダンプするルーチンの例です。DSPは繰返し処理が多いのでループの構造化がやりやすいようにできていて、ちょっと格好をつけてインデントを付けてみました。二重のループで横8ワード、縦16行の表示をさせる処理です。

f:id:O3I:20210705191037j:plain

 

(6)ループ制御

DO<address>UNTIL<condition>という命令があり、もうほとんど高級言語です。オーバーヘッドなしに<address>までの繰返しループを構成でき、回数やフラグ条件よる脱出が設定できます。しかもループカウンタCNTRはスタック構造になっていてループをネストさせても大丈夫です。ところがこれに引っ掛けがあってループの終端とその1つ前の命令ではスタックを触ってはいけない(CALLRTSを置けない)という制約があります。

f:id:O3I:20210705193103j:plain

最初これに気付かず所定回サブルーチンを呼ぶというコーディングをしたら指定した数を回らないとかループを抜けた後の飛び先がおかしいとか、1日悩みました。

 

(7)TOPPCSTACKアクセス

ADSP-21xxにはスタックに値を退避/復旧させるPUSH/POPに相当する専用命令がありませんが単に

 TOPPCSTACK=AX0;      /*  PUSH AX0  */

    AX0=TOPPCSTACK;      /*  POP AX0    */

の記述でスタック最上部へアクセスできます。ところがスタックというのはもともとCALL/RTSのとき戻りアドレスを保存するためのものであって全プログラム空間16kwordをカバーするのに十分な14ビット幅しかありません。上の例のように16ビット汎用レジスタに対して行ってもアセンブルも実行もエラーにはならずしれっと上位2ビットが欠落してきます。「FFFF」をPUSHしたはずなのに、POPしたら「3FFF」になってしまうのがどうしても判らず、3日悩みました。