MC6800のプログラミングテクニック(10) PSHX はできないけど、PSHSはできる

BASICMASTER, 昔のパソコン

6800でプログラムを書いていて困るのは、IXレジスタの加算減算命令がないことと、IXレジスタがPUSH/POPできないことである。

加算ができない弱点は1976年の富士通MB8861で解決されたのだけど、この改良はモトローラや日立にフィードバックされなかったので、オリジナルは不便なままであった。

根本的に解決されたのは1979年のMC6801/6803だが、同年に6809も発表され、パソコンでは6809が採用されるようになった。そりゃそうだよね。6809便利すぎる。

ローカル変数を必要とする言語では、スタックポインタ演算が必要

例えば、ローカル変数が10バイト必要ならSP=SP-10のような計算が必要である。MC6800にはそのような命令がないので、一度どこかにSPを保存してAccを使って加算するしかない。
(減らしたい数だけDESのループを回せばできないことはないけど…)

そして、SPの保存はSTS Direct/Extendだけだと思い込んでいた。これだとリエントラントにならない。

Reentrantは無理だと長年思っていたが、ふと気がついた。下記の命令でPUSHできるので なんとかなる、かもしれない。
(2バイトずれるけど、SP加算であれば加算する数を調整すれば良い)


	DES
	DES
	TSX
	STS 0,X

PULも同様である。同じテクニックでPULXも実現できるけど、PSHXはどうやっても無理。STXのインデックス修飾は役立たず命令になっている。


	TSX
	LDS 0,X


サブルーチン化してみる

毎回5バイトも使われると大変なので、サブルーチン化してみる。それでもJSRで3バイト喰うのだけど。

リターンアドレスを移動して戻るようにするために手間暇がかかる。JSRでスタックに戻りアドレスを積むので、保存されるアドレスはSP+4になる。

6800のインデックス修飾は0-255の正の数しか使えないから、先にDESが必要になり、それでSPがずれてしまう。仕方ないけど面倒くさい。


PSHS	DES
	DES
	PSHB
	TSX
	LDAB 4,X
	STAB 2,X
	LDAB 3,X
	STAB 1,X
	PULB
	STS  3,X
	RTS

ローカル変数のある言語なら、関数プロローグでSP修正処理を行うので、それと一緒にすればサイズや実行時間は気にならないかもしれない。


むりやりPSHX?

IXをPSHできる唯一の命令がSWIである。SWIをフックできる機種ならなんとかなるかも。
しかし、BASICMASTERのSWIはROMに焼かれていてどうしようもないんだよなあ。

BASICMASTERのモニタROMはよく出来てるんだけど、機能変更のためのフックが足りないのは時代的に無理もないか。
(BM Jr.ならモニタROM空間をRAM化できるので、SWIを書き換えて使う手はある)