6800のCPX命令とエミュレーター(2)(ベーシックマスター開発 その27)
6800のCPX命令とエミュレーター(1)(ベーシックマスター開発 その26) | ず@沖縄の続き。
MC6800のCPX命令は上位・下位を別々に引き算していて、N,Vフラグには上位同士の結果しか反映されないことはわかった。なぜそうなっているのだろうか?
これには2つの理由がある。
1. MC6800は8bit CPUであり、16bitレジスタも内部では8bitレジスタ2つとして処理されている。
2. MC6800はBig-endianである。
MC6800の内部構造
United States Patent US4090236 の図がわかりやすい。この特許には内部動作のフローチャートも書かれていて、MC6800が命令をどのように実行しているかを垣間見ることができる。
一目でわかるようにIXレジスタは上下8bitずつ別々のレジスタになっている。実はSPやPCですら8bit単位である。
演算装置としては右上に8bitのALUがあり、左上にインクリメンタ(INCL/INCH)がある。
右上のALUにつながっているレジスタは、AccA,BとIXH,IXL、CCRだけである。インクリメンタにはIXH/Lの他、SPH/L,PCH/Lがつながっている。両方に繋がっているのはIXだけである。
インクリメンタは±1を処理する。PC/SPの増減もインクリメンタが行うので、こちらは16bit計算である。
INX/DEXはインクリメンタ経由で演算を行ない、Zフラグに影響すると書かれている(Fig.2J)。
CPXでは引き算が必要なので、ALUを使う。ALUは8bitなので、IXH,IXLを別々に計算する。MC6800はBig-endianなので、計算に必要な値は上位バイトが先にメモリからフェッチされ、あとから下位バイトが取り込まれる。
Fig.2H に書かれているCPXの動作もそのようになっていて、先にIXHをALUで処理し、次にIXLを処理している。ZはALL 0’sのときに反映すると書かれている。
(Zなら下位の結果を
さて、16bit演算が必要な場合、下位バイトを処理した時に発生したキャリーを、上位バイトに反映しなければならない。
Little-endianのCPUであれば、先に下位バイトを処理して次に上位バイトの処理なので、自然にキャリーは反映できる。
しかし、MC6800はBig-endianのCPUなので、上位バイトが先である。キャリーを反映するには下位バイトを処理したあとに上位バイトを演算する必要がある。これには時間がかかる。1-2クロックぐらい遅くなるはず。また、その処理を行うためのトランジスタも必要になる。大騒ぎだ。
(富士通MB8861の追加命令ADXは16bit加算が行えるが、7clockかかる。CPXだと5clockなので2clock余計に時間がかかっている。トランジスタ数は約6000個※。MC6800の4100個の5割増である)
そこでMC6800では、潔くキャリー処理は諦めて上位バイトの比較結果のみをN/Vフラグに反映したのだろう。素直に処理するとIXLの結果になりそうだけど、IXHの処理結果が反映されているのは、使い道があると考えたからだろうか。
(これはLDX/STXでも同様。上位バイトのNフラグが設定されるので使い道がある)
追記:
MC6801/6803やMC68HC11ではCPXは16bit比較命令になっている。
命令実行時間はMC6800が3/4/6/5cyc、MC6801/6803では4/5/6/6cyc, MC68HC11では4/5/6/6/7cycになっている。
即値とダイレクト、エクステンデッドでは1cycずつ増えていて、上記推測は正しかったようだ。
インデックスアクセスはMC6801で高速化されて、1cyc早くなっている。MC68HC11では追加命令のCPX off,Yが 7cycであり残りはMC6801/6803と同じ。
MC68HC11のCPX命令の実行タイミングを見ると、命令実行の最後に1cyc増えているようだ。visual6800ではこのサイクルは見えないので、ここが増加分のようだ。
M68HC11 Reference Manual P.534より引用









ディスカッション
コメント一覧
まだ、コメントがありません