現在地

プログラミング

MC68020 / MC68030 の判別

カテゴリー:

アドレスエラー・バスエラー時の表示は、未対応のフォーマットの場合にはスタックに積まれたワードをそのまま16進ダンプするようにしたので、デコードルーチンは後回しにして判別を書くことにしました。

まずMC68020以上であることの判別は容易(MC68010の判別(補足)参照)なのですが、MC68020からMC68030で追加された命令はありません。というかあるにはあるのですがMMU関係の命令なのでMC68020+MC68851(PMMU)でも実行できてしまいます。細かな動作の違いはあるかもしれませんが...

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

カテゴリー:

前回までで従来の機能がセグメントモードで動作するようになりましたが、セグメントモードで動作するなら当然D(ump)などのコマンドでもセグメントが指定できなくてはなりません。

この辺りは8086のセグメントやTLCS-90のバンクを移植する形で対応しました。

表記はZ8000らしく<<SEG>>OFFSET形式も考えましたが、長くなるので8086同様SEG:OFFSET形式としています。

コマンドのパラメータ以外に対応が必要なのはR(egister)コマンドにおけるSSPとPCです。

  1. SSPH, SSPL, PCH, PCLのように16ビットずつ別のレジスタ名をつける
  2. 32レジスタとして扱う
  3. 16ビットずつに分けるが「:」で区切ってレジスタとしては1つとして扱う

などの方法が考えられます。

1.は勝手に名前を付けることになることと、2回に分けて設定するのは面倒です。

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

カテゴリー:

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

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

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

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

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

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

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

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

カテゴリー:

Z8001を動かすで非セグメントモードで動くことがわかりました。動作する石も複数確保できましたので、本来のセグメントモードで動かすことにします。

Z8000ファミリにはセグメントモードでも動作するZ8001(とZ8003)と非セグメントモード専用のZ8002(とZ8004)があります。両者はリセット時のPC, PSWの初期値を格納する形式が異なる上にアドレスが重なるので同一バイナリで両方に対応することはできません。

どちらの形式で読んでも辻褄の合う値を設定することは不可能ではありませんがメモリマップの制約が大きくなります。

Z8001(とZ8003)はセグメントモードでも非セグメントモードでも動作させることができます。これは同一バイナリで両対応するのは可能ですが、ほぼすべてのルーチンを2つ持つようなことになってしまいます。

結局3種類のバイナリを作ることになります。

アドレスエラー・バスエラー (その4)

カテゴリー:

アドレスエラー・バスエラーについて今度こそ終わりにするつもりです。

MC68040

MC68040からは大きな方向転換があったように感じます。

複雑度は増しているはずなのにスタックに積まれる情報は減っているのです。前にもMC68010の判別(補足)に書きましたが、命令の再開を諦めて頭からやり直す方針のようです。

まずはアドレスエラーの場合です。

アドレスエラー・バスエラー (その3)

3回目は残りですが書ききれるかなぁ。さらに1回増えてしまうかもしれません。

ここからは自分の手で動かしたことはないのでマニュアルを元にざっくり書いていきます。

MC68020 / MC68030

この両者はソフトウェアから見た例外処理はほぼ共通のようなのでまとめて書きます。

これらではエラー発生時の状況によってスタックに積まれる情報量に違いがあるようです。キリの悪いところで発生すると保存しないといけない項目が増えるということなのかな。

どちらが使われたかはSP+6の上位4ビットでわかります。

この4ビットでどのフォーマットかはわかりますが、それが何ワードなのかは書かれていません。
Universal MonitorではこれまでMC68010までの対応だったので0000なら4ワード、それ以外なら29ワードとしていました。それをMC68020以降で実行するとスタックがおかしなことになります。今回MC68010, MC68020, MC68030, MC68040, MC68060, SCC68070で使われているフォーマットとその長さをテーブルにして引くようにしました。

まずは少ない場合から。

アドレスエラー・バスエラー (その2)

カテゴリー:

前回はMC68000/MC68008について書いたので今回はMC68010/MC68012です。

MC68010 / MC68012

MC68000/MC68008ではアドレスエラー・バスエラーからのソフトウェアによる復帰はできませんでした。それを改善したのがMC68010(とメモリ空間を拡大したMC68012)です。

そのためには例外処理を行なっている間復帰に必要な内部状態を保存しておかなくてはなりません。内部にこっそり保存するという方法も考えられなくはありませんが、MC68010ではスタックに積むことで保存します。

アドレスエラー・バスエラー発生時のスタックには以下のように29ワードという大量の情報が積まれています。

アドレスエラー・バスエラー

カテゴリー:

Universal Monitor 68000は自分のボードで動かせるMC68000, MC68010まで対応し、MC68020以降は動かす人もいないだろうから後回し、と思っていたのですが...

なんとMC68030で動かした方がおられます(リンク参照)。

これは判別やら例外処理やら対応しなくてはと思いソースを見たところ、MC68010のアドレスエラー・バスエラーの表示を作りかけたままになっておりました。これを放置したまま他の変更を行なうのは混乱の元(一応 Subversion で管理してはいますが...)なのでまずこれを完了させることにしました。

MC68000系では割り込みの他、ゼロ除算や未定義命令の実行などが発生したときにあらかじめ用意したルーチンを実行する機能があります。これを例外処理といいます。

原則として(復帰できるように)発生時のPCとSRをスタックに積んでから実行するのですが、アドレスエラーとバスエラーの場合はさらに多くの情報がスタックに積まれます。

HD1-6120ボード(モニタ移植編)

カテゴリー:

HD1-6120ボードを作ってから約2年、ASが使えるようになったのでUniversal Monitorの移植に着手しました。

ボード完成以来ソフトウェア編での無限ループ確認くらいしかしていなかったのですが、やっとまともなプログラムが動かせます。いくつかあった問題は、ASはIM6100対応を行ない、EMILY Boardも12ビット8進表示モードを作ったことでほぼ解決しています。

残るUniversal Monitorの仕様は... 常に8進表示でダンプ時のASCII表示は無しとすることにします。

そう決まればあとは黙々と実装するのみです。

現在 D(ump), G(o), S(et) の各コマンドができて L(oad) はインテルHEXのみ実装してデバッグ中といった状況です。

ある程度のプログラムを書いてこのIM6100の癖がわかってきたので書いてみたいと思います。

ASのIM6100対応(その4)

カテゴリー:

前回の最後に複合命令の処理がイマイチと書いたのは次のようなことです。

     	SNL MQA

SNLはグループ2ですから次のMQAは共通命令テーブルとグループ2の命令テーブルを探すことになります。ところがこれはグループ3なので当然見つかりません。

結果として"unknown instruction"エラーになるわけですが、MQAは存在する命令でただSNLとグループが違っているだけです。"invalid instruction combination"エラーの方がより親切というものでしょう。

そこですべてを1つの命令テーブルに入れることにしました。各命令ごとに複合命令にできるか、できるならどのグループかの情報を付加して組み合わせられるか判定します。

ページ