6800の分岐命令(ベーシックマスター開発 その30)

2024/09/20BASICMASTER, 昔のパソコン

6800には豊富な分岐命令がある。複数の条件フラグを参照する分岐命令もあり、プログラミングを楽にしてくれる……はずなのだけど、うっかりすると罠にハマってしまう。実際ハマった。

解説資料も少なくて、初学者の参考になるようなサイトも見つけきれなかった。そこで6800の分岐命令の解説資料を書いておく。いまどき6800の初学者が存在するのかわからんけど。

分岐命令の詳細はMC6800のマニュアルに書かれている。日立ベーシックマスターのマニュアルにも解説はある(バグもあるが)。

M6800 Microprocessor Applications Manual 1-32 より引用

だけど、これだけではわかりにくいので、分岐条件を表にして整理してみた。

1バイトの符号なし比較と分岐

符号なし比較は簡単である。SUB/CMP命令でレジスタからメモリの値を引いて、C/Zフラグを見れば良い。CとZ両方を見るBHI/BLSもあるので、全パターンが1分岐命令で判断できる。

CPX/LDX/STX命令でもZフラグは立つので、2バイトの数値が等しいか・等しくないかは簡単に比較できる。

CPX/LDX/STXではCフラグは変化しないので大小関係はわからないが、変化しない方が多倍長演算が楽なのでこの仕様になったのだろう。

1バイトの符号あり比較と分岐

符号ありの場合は、結果の正負とオーバーフローの有無の両方を見ないといけない。
幸い、6800の分岐命令は両方を見て判断してくれるので全パターンを1命令で判断できる。

AccへのSUB/CMP命令の直後に下の表を見ながら分岐命令を書くだけで良い。楽ちんである。


複数の条件が絡むので、表にしないと実にわかりにくい。実際、I/O誌にも「意外とアヤフヤで使っている人の多い 条件分岐の完全理解」(I/O 1981年11月号 P.242)という記事が載ったほどである。

「意外とアヤフヤで使っている人の多い 条件分岐の完全理解」I/O 1981年11月号 P.243より引用


符号あり数値の正負判定

符号ありの数値が正(>=0)か負(<0)かを見るには符号ビット(bit 7)を見れば良い。これはBPL/BMIで判断できる。 LDX/STXでもNフラグは変化するので、正負だけなら2バイトの比較も簡単だ。 CPX #0やLDX/STXの後なら、Zも使えるので、2命令使えばZ>0もわかる。


	LDX	Var
	BEQ	EQUAL	; Z=0
	BPL	PLUS	; Z>0
	...		; Z<0

実は正負だけなら、2バイト目を見る必要すらないので、TST命令で最初のバイトだけ調べても良い。TSTは遅いので、レジスタを壊しても良いならLDA/LDXの方が早い。


	TST	Var
	BPL	PLUS	; Z>=0
	...		; Z<0


2バイトの比較と分岐命令

2バイトの比較はMC6800では鬼門である。MC6809にはCMPD命令があり、MC6301にもCPDがあるので2バイト比較は1バイト比較と同様に行える。

しかし、MC6800では限られた場合を除き、1バイト単位で比較しなければならない。

もっとも、MC6809/MC68HC11であっても、3バイト以上の多倍長演算では面倒臭い比較作業が必要になる。

6809用のCコンパイラであるacwjも、LONG(4bytes)の比較の部分には、// XXX This isn't right and I need to fix itなどと書かれていたりする。

2バイトの符号なし比較と分岐

さて、MC6800での符号無し・2バイトの比較表は以下の通りである。

1バイト比較と違うのは、上位バイトを見ただけでは判断できない場合があるので、2バイト目も見ないといけない場合がある、ということである。

例えば、2バイトの数値が0と等しいかどうかは、上位1バイトを見ただけではわからない。上位が0であっても下位は0でないかもしれない。
(逆に上位が0でなければ、0でないことはわかる)

したがって、0と等しいかの判断は以下のようにプログラムする。AとBをORできる命令があれば楽なんだけど、そんな命令はないので面倒なことになっている。

(ABA/CBA/SBAが有るのだから、AND/OR/EORも作って欲しかった)


	TSTB
	BNE	NotEqual
	TSTA
	BNE	NotEqual
	...			; ==0


2バイトの符号あり比較と分岐

以下は2バイト符号ありの場合である。やはり、上位バイトだけを見たのでは結果がわからない場合がある。

L<=R の場合、下記のようなコードになる。1バイト比較では1命令で判断できたが、2バイト比較では分岐命令を2-3命令必要とするので、遅くなるし、わかりにくい。


	LDAB	L+1
	LDAA	L
	SUBB	R+1
	SBCA	R
	BGT	False
	BNE	True
	TSTB
	BNE	False
True:	:
False:	:

上位バイトを見ただけで判断できる場合もあり、それは A>=M (BGE) と A<M (BLT)の場合である。これはコンパイラの最適化のテクニックとして使える。

日立ベーシックマスター取扱説明書のバグ

BLSの説明として「C BitがセットかあるいはZ Bitがクリアなら」とあるが、これは「Z Bitがセットなら」の誤り。動作説明は "PC←(PC)+0002+Rel, if (C)⊙(Z)=1" であり、正しい。


参考文献

  • M6800 Microprocessor Applications Manual
  • MB6881 日立ベーシックマスターレベル2II取扱説明書
  • MB6885 ベーシックマスターJr取扱説明書
  • 「意外とアヤフヤで使っている人の多い 条件分岐の完全理解」I/O 1981年11月号 P.243