2022-07-20 11:28 — asano
カテゴリー:
第2回目はメモリ参照命令についてです。
IM6100のメモリ参照命令は6つ(うち2つはジャンプ系)しかありません。フォーマットも単純です。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|
Op Code (0-5) | IA | MP | Page Relative Address |
Op Code部が6の場合は入出力のIOT命令、7の場合はOperate命令(前回の複合命令はこれ)です。
IAは"Indirect Addressing"で、0の場合は"Direct Addressing"を表し以下で決まるアドレスがEffective Address(以下EA)に、1の場合は"Indirect Addressing"を表し以下で決まるアドレスのメモリを参照しその値がEAとなります。
MPは"Memory Page"ですが、その前にIM6100系(の元になったPDP-8)のメモリとそのアドレスについて簡単に書いておきます。何せ磁気コアメモリの時代のアーキテクチャなのであまり大容量のメモリを搭載することは想定していません。
まず12ビットが1ワードです。命令フェッチも含めすべてのアクセスは1ワードです。
次に128ワードを1ページと呼びます。この範囲を超えるとアドレス指定が面倒になります。
メモリ拡張機構のあるHD1-6120ではさらに32ページを1フィールドと呼び、この範囲を超えるとバンク切り替えのような感じになりさらに面倒になります。
メモリ拡張の無いIM6100では32ページ=4kW、あるHD1-6120では8フィールド=32kWが扱える最大メモリになります。
MPに戻ると、0の場合はページ0を、1の場合は現在(のPC)のページがアクセス対象になります。
Page Relative Address(以下PRD)は上で決まったページ内のアドレスです。"Relative"とありますがPC相対アドレッシングのようなものではなく、ページ先頭からのオフセットになります。
例えば PC=4036(8) にある命令で IA=0, MP=1, PRD=072(8) だったとすると、現在ページはページ20(8), ページ先頭は4000(8)なのでPRDを加えて4072(8)がEAになります。
もう一つ、IA=1, MP=0, PRD=010(8)とするとページ0の0010(8)をまず読み、読み込まれた値がEAになります。
0ページか現在ページ以外を直接アドレスできないので、どちらかのページにアドレスを置いておいてIA=1でアクセスするというのが基本になります。
アセンブラ書くのに命令の動作はあまり関係ないのではと思うかもしれませんが、エラーチェックをちゃんとしようと思うとどうしても必要になります。
例えば次のソースをアセンブルすることを考えます。
JMS LABEL
まずJMS
のコードは4000(8)、DirectなのでIA=0です。
MPですが、これはLABEL
のアドレスが必要です。もしページが0ならMP=0です。もし0でないならこの命令の置かれるアドレスのページと比較して一致するならMP=1、不一致ならアクセスできませんのでエラーにしなくてはなりません。
メモリ拡張機構
メモリ拡張機構はこうして決まった12ビットのアドレスにさらに3ビットを追加します。この3ビットはIF
(Instruction Field)・DF
(Data Field)と呼ばれるレジスタから提供されます。前者は命令フェッチ・Directアクセス・Indirectアクセスの前半(ポインタアクセス)に使用され、後者はIndirectアクセスの後半(データアクセス)に使用されます。
IF
, DF
の変更にはそれぞれCIF
, CDF
という専用命令を使用しますが、面白いのはCIF
を実行してもすぐにIF
は変更されず、IB
と呼ばれる一時レジスタのみ変更され次のJMP
あるいはJMS
の実行直後にIB
からIF
にコピーされるという点です。
エラーチェックのためにはIF
, DF
がいくつに設定されているか知らなくてはなりません。IF
は命令の置かれる場所で決まりますから簡単です。DF
に関してはどうせチェックできないので無視します。
あとはアクセス先のフィールドとIF
が一致することを確認するだけです。
一つ例外として考えなくてはならないのはDirectのJMP
とJMS
です。
CIF 5
...
JMP LABEL
この場合JMP
命令実行直後にIF
が更新されるのでジャンプ先の命令フェッチはフィールド5になりますから、LABEL
のフィールドも5でなくてはなりません。この値はアセンブラにはわからないのでASSUME
疑似命令で指定できるようにしておきます。
アドレスの確定について
これはIM6100固有の問題ではありませんがアドレスのチェックを行なう場合はアセンブル中いつアドレスが確定するか意識していなくてはなりません。
JMP LABEL
LABEL:
これは前方参照の例ですが、パス1でJMP
命令を処理している時点ではLABEL
の値は(存在するかも含め)未確定です。EvalStrIntExpression(&ArgStr[1], UInt12, &OK);
などとすれば文法的に合っていればOK
にはTrueが入ってきますが、値は不定なのでこれでアドレスチェックなどしてしまうとエラーになってしまう可能性があります。
また前方参照以外にも値によって命令長が変わる場合(IM6100にはそのような命令はありませんが)など最終パスまでは値が確定しないことがあります。
そのような場合は以下のようにします。
Adr = EvalStrIntExpressionWithFlags(&ArgStr[adrPos], UInt15, &OK, &Flags);
文法的にあっているかはOK
でわかり、式の中に値の確定していないものが含まれているかはFlags
を精査することでわかります。
例えば今回のIM6100ではアドレスチェックの条件として以下を入れています。
if (!mFirstPassUnknownOrQuestionable(Flags))
これが成り立たない場合は必ず次のパスがありますから今パスではチェックをスルーしても問題ありません。
コメントを追加