現在地

Z8000セグメントモード対応(その2)


カテゴリー:

前回枠組みができたので実際に変更していきます。

直接アドレスやJR, CALRなどの相対アドレスはアセンブラが良きに計らってくれるので書き直す必要はありません。

問題はレジスタ間接(インデックスなども含む)です。これは単純に書き換えられない上に、アドレスレジスタが隣り合う2つのレジスタをペアにする関係でレジスタの割り当てを大きく変更する必要がありました。幸いレジスタ数に余裕があったためレジスタ番号の書き換え程度で済んでいますが、不足する場合はメモリに退避するなど変更規模が大きくなってしまいます。

今回は大きく3つのパターンで対応しました。

単純に32ビットレジスタへ置き換え

レジスタ間接のまま32ビット化するのが一番手っ取り早いのですが、レジスタをペアで使用するので多用するとレジスタが足りなくなる恐れがあります。

これはどこを指すかわからない場合に使用しました。具体的にはSTROUTルーチンへの引数と各コマンドでの対象メモリへのアクセスです。

前者についてはモニタ内の固定文字列の出力にしか使用していないので後述のインデックスでも可能なのですが、文字列出力はモニタ外からも使用できるようにしておいた方が便利だろうということでレジスタ間接を使用しています。

後者はもちろんユーザがどこにアクセスしようとするかはわからないので必然的にレジスタ間接になります。

ポインタから配列へ

これまで入力バッファのアドレスをR1に入れて@R1でアクセスしていたのを、先頭からのオフセットに変更しINBUF(R1)でアクセスするようにします。

C言語でいうところの*p++からINBUF[i++]に置き換えるようなものです。

アクセスする命令に32ビットの先頭アドレスが付くのでコードが長くなってしまうのですが...

アクセスするのはGETLIN, RDHEX, SKIPSPなど限られたルーチンがほとんどなのでそれほどの悪影響はありません。一方、これらのルーチンを汎用に使うことはできなくなってしまいました。

D(ump)コマンドのアスキー表示用バッファも同様です。

レジスタ関係テーブルのリンク

主にレジスタ関係の処理でテーブルを多用しています。これらのテーブルはポインタでリンクしているので、ポインタを32ビットにするとテーブルサイズが変わってしまいます。また数も多いのでテーブルサイズがかなり大きくなってしまいます。

そこで...

これもインデックスアドレッシングに書き換えました。ただ原点をどこにするか、少し悩んだ挙句セグメントの先頭にしました。こうするとオフセットの算出が楽になります。

元々1(R4)のようにインデックスを使っていたところは原点+1のようにします。定数同士なのでアセンブル時に解決されます。

コードとしては簡単なのですが、セグメントモードと非セグメントモードでソースを共有するのがちょっと面倒でした。

CSEG0 = (CODE_B & 0FFFF0000H)

といった変な式があるのはそのためです。

前回示したAR1のようなレジスタの置き換えも含め、セグメント / 非セグメントモードでソースを共通にできるメリットの半面、ソースの字面がZ8000らしくなくなってしまいます。

参考文献・関連図書: 
『Z8000ユーザーズ・マニュアル [1]CPU/MMU編』, シャープ.

コメントを追加

Plain text

  • HTMLタグは利用できません。
  • ウェブページアドレスとメールアドレスは、自動的にハイパーリンクに変換されます。
  • 行と段落は自動的に折り返されます。
※ コメントは原則公開です。個別のご相談などは「ご意見・ご要望」からお願いします。