現在地

MC68010の判別


SH7045ボードへのUniversal Monitorの移植に着手したのですが、その前にMC68000系で動くようになっていますのでそのあたりの話を何回かに分けて書こうと思います。

MC68000自体は30年ほど前にいじっていて(だから未経験のプロセッサを優先して後回しになっていました)サクサク書いていたのですが、これまで書いたことがなかったのがプロセッサの識別です。

当時からMC68010は載せていましたがモニタは専用にアセンブルしていました。

N BASIC上で動く簡易クロスアセンブラを使用していたので条件アセンブルなどはできずソースを別個に管理していたように記憶しています。

ですからMPUを載せかえる時はROMも一緒に交換です。

今回は基本部分がすんなり動作したので識別ルーチンに挑戦することにします。

識別の原理はもちろんプロセッサによる挙動の違いを検出するわけですが、これにはいくつかのパターンがあります。

  1. 識別のための命令・機能
    PentiumのCPUIDのような命令があれば簡単です。あるいはリセット直後に特定のレジスタに識別用の情報が入っている場合もあります。
  2. 命令の動作の違い
    命令互換のプロセッサでも通常問題にならないような動作の違いがあることがあります。あまり使われない(命令の目的と関係ない)フラグの変化であったり、無意味な動作(8ビットレジスタを8ビット以上シフトするとか)などです。設計上の都合などでこれらの違いが生じても普通問題にならないのでそのままになっていたりします。あるいはあるプロセッサを元に別メーカが異なる拡張を行なった場合などはまったく違った動作をすることもあります。
  3. 片方にしかない命令
    8080に対してZ80で追加された命令などがこれに当たります。片方のプロセッサでは未定義な命令を実行することになるので副作用に注意が必要です。たとえば6800のHCFのようにソフトウェアで回復できないような命令は使用できませんし、互換プロセッサで何が起きるかわからないリスクもあります。

まず1.に相当する命令等はありません。

2.だといくつか思い当たるものがあります。まずMOVE SR,<ea>がMC68010では特権命令になっているのでユーザモードで実行してみる方法が考えられます。例外を発生させた時にスタックに積まれる量が異なるのでSSPの変化を見る方法もあります。

数は少ないですが追加された命令もあるので3.も使えます。幸い未定義命令を実行すると不当命令例外になるので副作用の心配はあまりありません。

いずれにしても例外処理が絡むので6800やZ80などのようなシンプルな分岐ではすみません。今回は68010にしかないMOVEC VBR,D0命令を実行して不当命令例外が発生するかチェックすることにしました。

まずはメインルーチンを抜き出してみます。

     140/  30014E : =>TRUE              	IF USE_IDENT
     141/  30014E :                     
     142/  30014E : 41F9 0030 0C17      	LEA	IM000,A0
     143/  300154 :                     	SAVE
     144/  300154 :                     	CPU	68010
     145/  300154 : 4E7A 0801           ID0:	MOVEC	VBR,D0		; Try MC68010 instruction
     146/  300158 : ALL                 	RESTORE
     147/  300158 : 41F9 0030 0C21      	LEA	IM010,A0
     148/  30015E : 13FC 0001 0009      	MOVE.B	#1,PSPEC
           300164 : FF2C             
     149/  300166 :                     ID1:
     150/  300166 : 6100 05EC           	BSR	STROUT
     151/  30016A :                     
     152/  30016A : [140]               	ENDIF

145行で問題の命令を実行します。68010であれば正常に実行されD0にはVBRの初期値である0が入ります。

続いて147,148行で文字列"MC68010",CR,LF,0のアドレスとMC68010を表す1を設定します。

150行で文字列を表示して終了です。

68000/68008の場合は145行で不当命令例外が発生して例外ハンドラに処理が移ります。このハンドラは次のようになっています。

     992/  3008BC :                     	;; 04 Illegal Instruction
     993/  3008BC :                     ILLINS_H:
     994/  3008BC :                     	;; Check IDENT
     995/  3008BC : =>TRUE              	IF USE_IDENT
     996/  3008BC :                     
     997/  3008BC : 0CAF 0030 0154      	CMP.L	#ID0,2(A7)	; Check PC on system stack
           3008C2 : 0002             
     998/  3008C4 : 660C                	BNE	ILLINS0		; PC is not IDENT routine
     999/  3008C6 :                     
    1000/  3008C6 : 5C4F                	ADDQ	#6,A7		; Drop stack frame
    1001/  3008C8 : 4239 0009 FF2C      	CLR.B	PSPEC
    1002/  3008CE : 6000 F896           	BRA	ID1
    1003/  3008D2 :                     	
    1004/  3008D2 : [995]               	ENDIF
    1005/  3008D2 :                     
    1006/  3008D2 :                     ILLINS0:
    1007/  3008D2 : =>TRUE              	IF USE_REGCMD
    1008/  3008D2 : 48F9 7FFF 0009      	MOVEM.L	D0-D7/A0-A6,REGD0
           3008D8 : FF38             
    1009/  3008DA : =>FALSE             	ELSE
    1010/  3008DA :                     	MOVEM.L	D0-D3,REGD0
    1011/  3008DA :                     	MOVEM.L	A0-A3,REGA0
    1012/  3008DA : [1007]              	ENDIF

まず997行でスタックに積まれている戻りアドレスが判別ルーチン内のMOVEC VBR,D0命令のアドレスであることを確認します。異なっていれば998行で通常の不当命令例外の処理に戻してやります。

1000行ではA7(これは例外ハンドラ内では常にSSP)に6を加えていますが、例外発生時にPCSRが計6バイト分スタックに積まれているのでこれを取り除きます。

1001行では68000/68008を表す0を設定します。

1002行でメインルーチンに戻ります。かなり乱暴な戻り方ですが発生場所が特定されているので問題ありません。

次回はブレーク処理についてを予定しています。

参考文献・関連図書: 
Motorola『M68000マイクロプロセッサ ユーザーズ・マニュアル 4th edition』, CQ出版社.

コメントを追加

Plain text

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