MC6800のプログラミングテクニック(9) シフト・ローテート命令のVフラグ

BASICMASTER, 昔のパソコン

NEG命令が意外に使える命令だとわかったので、他にも特殊なフラグ変化をする命令がないか探してみた。あった。

シフト・ローテート命令群のVフラグの変化に特記事項⑥がついている。

M6800 Microprocessor Applications Manual, Motorola 19751-18 より引用

⑥の解説には以下のように書かれている。シフト後のNとCの排他的論理和になるらしい。

⑥ (Bit V) Test: Set equal to result of N ⊕ C after shift has occurred.

ベーシックマスター L2II / Jr. のマニュアルでも同様。

もし、操作の結果、“NがセットでCがクリア” かあるいは “NがクリアでCがセット” ならばセット、さもなくばクリア

BASIC MASTER MB6881 ベーシックマスター レベル2II 取扱説明書, HITACHI P.123 より引用


MC6809のマニュアルではどうなっているか

記述が異なっている部分がある。例えば、ASR命令では、Vは Not affectedである。

R – Not affected

MC6809-MC6809E 8-Bit Microprocessor Programming Manual (Motorola Inc.) 1981 A-10より引用

一覧にしてみた。右移動がNot Affected、左移動の場合は、命令実行前のb7とb6のxorになる。

左移動では、b7がCに、b6がb7に移動するので、移動後のCとb7(N)とのxorでもある。結局は、モトローラ1975やベーシックマスター取扱説明書と同じことを明快に書いているだけだ。

他の文献も調べてみたが、右移動でのフラグ変化は非互換のようだ。

命令Vフラグ変化
ASL/LSLLoaded with the result of the exclusive OR of bits six and seven of the original operand
ASRNot affected
LSRNot affected
ROLLoaded with the result of the exclusive OR of bits six and seven of the original operand.
RORNot affected


困った時はvisual 6800

念の為、6800でのフラグ変化をVisual 6800を使って確認してみた。Visual 6800はトランジスタレベルでシミュレートしてくれる優れもののシミュレーターだ。




確認方法

下記のような短いコードを書いて、値を変えながら確認してみた。


	LDAA #$80
	LSLA


全命令でモトローラのマニュアル通り、N⊕C になっていた。

他のエミュレーターには、右シフトでは6809同様にVを変化させないものがあった。困る。

Vフラグの変化は何に使えるか?

あまり使い道を思いつかないのだけど、無理やり考えたのが、AccA,Bが同符号であるかの判定。

以下の3命令で同符号ならV=0, 異符号ならV=1になる。Bは破壊されない。Aも壊したくなければ、ASLAの代わりにASRA/ROLA。

RORB/ROLB は ROLB/RORB でも良い。


	ASLA
	RORB
	ROLB

通常はEORを使うのだけど、レジスタ間EOR命令はないので、メモリへの退避が発生する。Bを破壊したくなければ、PSHB/PULBが必要。


	STAA @tmp
	EORB @tmp



右シフト(ASR/LSR)はb7がセット/リセットされるので、結局元のb0の値が!V/Vになるだけである。この用途はCで間に合う。

右ローテートの場合は、元のCとb0のxorになるのだが、こちらは用途を思いつかない。

ASRA/RORBでレジスタ間でのb0同士の排他的論理和が計算できるのだけど、それはABA/ANDA #1 やABA/ASRAで良い。非互換問題も発生しない。

追記

左シフト・ローテートだと、元々のb7とb6の xor を検出できる。

2進数で 00000000〜00111111の範囲と、11000000〜11111111の範囲はV=0、それ以外がV=1である。

10進だと0〜63、-64〜-1 の範囲であり、ある1バイトの数値が -64〜63 の範囲であるかを1命令で検出できる。できるけど使い道あるかなあ…