アドレスエラー・バスエラー時の表示は、未対応のフォーマットの場合にはスタックに積まれたワードをそのまま16進ダンプするようにしたので、デコードルーチンは後回しにして判別を書くことにしました。
まずMC68020以上であることの判別は容易(MC68010の判別(補足)参照)なのですが、MC68020からMC68030で追加された命令はありません。というかあるにはあるのですがMMU関係の命令なのでMC68020+MC68851(PMMU)でも実行できてしまいます。細かな動作の違いはあるかもしれませんが...
MC68020にのみ存在する(MC68030では削除された)命令ならCALLM , RTMがあります。これらはかなり複雑な命令なので判別のためだけに使うのは大げさですが、それでもただ呼び出して戻ってくるだけなら難しくもないかなと使ってみることにしました。
まずMC68000/MC68008を除外して、MC68010以上であることが分かったあと以下を実行します。
     151/  300158 :                     	SAVE
     152/  300158 :                     	CPU	68020
     153/  300158 : 06F9 0000 0030      ID1:	CALLM	#0,MDESC	; Try MC68020 instruction
           30015E : 0E9C             
     154/  300160 : ALL                  	RESTORE
     155/  300160 : 41F9 0030 0E87      	LEA	IM020,A0
     156/  300166 : 13FC 0002 0009      	MOVE.B	#2,PSPEC
           30016C : FE2C             モジュールを呼び出して、無事に戻ってくればMC68020確定です。MC68010やMC68030以上の場合は不当命令例外が発生するので、MC68000の時と同様スタックを戻して次の判別に進みます。
CALLM命令のオペランドの#0は渡す引数がないこと、MDESCは呼び出し先モジュールのアドレスなどの情報が入ったモジュール・ディスクリプタのアドレスです。
    1604/  300E9B :                     	;; Module Descriptor for CALLM
    1605/  300E9B :                     	ALIGN	4
    1606/  300E9C :                     MDESC:
    1607/  300E9C : 0000 0000           	DC.L	$00000000	; Opt=000, Type=$00, AL=$00
    1608/  300EA0 : 0030 0E0C           	DC.L	DMYRTM		; Module Entry Word Pointer
    1609/  300EA4 : 0000 0000           	DC.L	$00000000	; Module Data Area Pointer
    1610/  300EA8 : 0000 0000           	DC.L	$00000000本来はいろいろ凝ったことができるはずなのですが、ここでは実行できるか確かめたいだけなのでほとんどが0という何のためにモジュール機能を使うのかわからないシンプルなものとなっています。
モジュール本体も何もしないものとなっています。
    1571/  300E0C :                     	SAVE
    1572/  300E0C :                     	CPU	68020
    1573/  300E0C :                     DMYRTM:
    1574/  300E0C : F000                	DC.W	$F000		; A7
    1575/  300E0E : 06CF                	RTM	A7
    1576/  300E10 : ALL                  	RESTOREこのモジュール機能はMC68030で削除されたことからもわかるように、あまり使われなかったようですね。
CALLMが不当命令で実行できなかった場合は続いてMC68030以上であるかチェックしていきます。既にMC68020は除外されているので、MC68020で追加された命令が実行できればMC68030以上であるとわかります。
     160/  300170 :                     	SAVE
     161/  300170 :                     	CPU	68030
     162/  300170 : 4E7A 0002           ID3:	MOVEC	CACR,D0		; Try MC68020 instruction (since MC68020 already eliminated, this checks MC68030)
     163/  300174 : ALL                  	RESTORE
     164/  300174 : 41F9 0030 0E91      	LEA	IM030,A0
     165/  30017A : 13FC 0003 0009      	MOVE.B	#3,PSPEC今回はMC68020で追加されたキャッシュ制御レジスタが読めるか試しています。
CALLMより簡単だったかもしれません。まぁこちらを使う場合も立てても問題ないビットはどれかなど考えなくてはならないことはあるでしょう。
これも正常に実行すれば(下に流れてくれば)MC68030以上が確定です。不当命令例外が発生すればMC68010(とMC68012)が確定します。
今回追加したのはここまでです。
MC68040, MC68060は... さすがに動かす人はいないだろうと... いたらその時考えます。
SCC68070は、ちょっと厄介かもしれません。まだマニュアルをよく読んでいませんが、命令はMC68000と同じなのに例外時のスタックフレームはMC68010以降と同様のようなので、今のコードだとSSPがずれるかも。逆にそこを利用できる可能性もありますが。今後の課題ですね。
現時点でMC68030, MC68EC030は正常に判別したと連絡を頂いております。
コメントを追加