2019-07-09 22:59 — asano
現在のCPUではその種類や対応する命令の範囲などを取得する命令(例えばx86系のCPUID命令)がありますが、以前は微妙な挙動の違いなどから判別していました。
自作のUniversal Monitorのソースコードを例に解説してみます。
MC6800系
まずは昨日目処が立ったと書いたMC6800系からです。
この系統はあまり情報が無く(旬な時期にあまりかかわらなかったのも理由です)手持ちのデバイスで試しながら書いたものです。
該当部分のソースは次のようになっています。
47/ E02C : CE 55 AA LDX #$55AA
48/ E02F : C6 64 LDAB #100
49/ E031 : 86 05 LDAA #5
50/ E033 : 8B 05 ADDA #5
51/ E035 : 18 FCB $18 ; DAA on 6800, ABA on 6803, XGDX on 6303
52/ E036 : 81 55 CMPA #$55
53/ E038 : 27 1E BEQ ID_6301
54/ E03A : 81 6E CMPA #110
55/ E03C : 27 13 BEQ ID_6801
56/ E03E : 81 10 CMPA #$10
57/ E040 : 27 09 BEQ ID_6800
肝は51行目の$18です。このオペコードは各プロセッサで次のように解釈されます。
- MC6800ではDAA(Decimal Adjust A, 加算後の十進補正)命令 (未定義命令)
49,50行目で 5+5 = 10 = $0A がAレジスタに入っています。ここで十進補正を行なうのでAは$10となります。 - MC6801,MC6803ではABA(Add Accumulators, A+B→A)命令 (未定義命令)
48行目でBレジスタには100が入っているのでAは110となります。 - HD6301,HD6303ではXGDX(Exchange D X, D↔X)命令
DレジスタはAを上位, Bを下位とする16ビットレジスタなので$0A64、Xレジスタには47行目で$55AAが入っています。これを入れ替えるのでA(Dの上位)は$55になります。
あとはAの値で分岐するだけになります。
この$18命令はHD6301,HD6303以外では未定義命令で何が起こるかは保証されていません。上記は手持ちのMC68A00P,MC6803Pで実験した結果にすぎないので異なる動作をするものの存在を否定できません。特に命令の拡張されているMB8861などは心配です。
MB8861の判別も書いてみたいのですが、現物を入手しないことには...
MC6809系
こちらは「THE 6309 BOOK」にMC6809と日立のHD6309の判別方法が載っています。
36/ E021 : 34 06 PSHS D
37/ E023 : 10 43 FDB $1043 ; COMD on HD6309, COMA on MC6809
38/ E025 : E1 61 CMPB 1,S
39/ E027 : 35 06 PULS D
40/ E029 : 26 06 BNE ID_6309
37行目の$1043がキーになります。
- MC6809ではCOMA(Aのビット反転)
1バイト目の$10はプレフィックスですが2バイト目との組み合わせが未定義の場合はNOP扱いになり、2バイト目の$43(COMA)として実行されるそうです。これは未定義動作です。 - HD6309ではCOMD(DつまりAとBのビット反転)
38行目でスタックに保存してあった元BとBを比較することによって区別します。MC6809ならBは変化しないので一致し、HD6309では反転しているので不一致になります。
やはりMC6809の未定義の挙動に依存しているという心配はありますね。
次回は8080,Z80系について書く予定です。
参考文献・関連図書:
MC6800データシート, Motorola.
MC6801,MC6803データシート, Motorola.
HD6303R,HD63A03R,HD63B03Rデータシート, Hitachi.
Chris Burke, "THE 6309 BOOK", Second Edition.
MC6809Eデータシート, Motorola.
HD63B09, HD63C09データシート, Hitachi.
コメントを追加