MC6800のプログラミングテクニック(18) BYTE SAVING PROGRAMMING TRICKS FOR THE 8080

BASICMASTER, 昔のパソコン

Dr. Dobb’s Journal という、書名だけでは内容がわからないマイコン雑誌があった。一時期は日本語版も発売されていた。プログラミングテクニックが掲載されていて、私も参考にしたものだ。

さて、その DDJ誌に “BYTE SAVING PROGRAMMING TRICKS FOR THE 8080” というTom Pittman氏の記事があった(June/July 1976, P.9-10)。

題名の通り 8080でのプログラミングテクニックの記事だが、6800でも参考になるので紹介する。

Carry を1byteに拡張

1バイトのsigned charを、2バイトintに符号拡張したい場合、charのb7に応じて上位バイトを$00または$FFにする必要がある。そのときに使えるテクニック。

8080では、レジスタ-レジスタ間の演算ができるが、両方ともAレジスタを指定することができる。

SBBは Areg – reg – Carry という命令で、SBB Aとすることで、A-A-C、つまり $00-C が計算できる。Carryが立っていれば A=$FF, C=0 なら A=$00 である。便利。

For 2’s complement signed arithmetic, it is some¬ times necessary to add a signed 1-byte number to a larger format. There are also other reasons for spreadingasingle bit (in the Carry FF) to a whole byte (in A). I found this one in the Scelbi book:

SBB A Copy carry to all bits in A

“BYTE SAVING PROGRAMMING TRICKS FOR THE 8080”, Dr. Dobb’s Journal, June/July 1976, P.9



つい最近、6800でAccABの右15bitシフトを高速化できないか考えた。unsignedなら簡単。8cyc, 4bytes。 Carry経由でAccAのb7を AccBのb0に移動する。


	clrb
	asla
	rolb
	clra

問題はsignedのときだ。素直に書くと asra / rolb を15回繰り返すのだが、そんなことはやってられない。最初をtabにする手もあるが、焼け石に水である。

8080のように、0-C の操作ができれば良いのだが、1命令では残念ながら不可能。clrb と sbcb #0 が必要になる。


	clrb
	asla
	sbcb	#0
	tba

応用として、signedの右14bitシフト。Carryフラグを壊さないようにコードを並べる必要がある。右シフトなのに、左シフト命令しか出てこないのが面白い。


	clrb
	asla
	sbcb	#0
	asla
	tba
	rolb


Carryをb7に移動する

Aregのb7をCarryで置き換える。8080のRLC/RRCはb7とb0を直接つないで回転(Rotate)できるので、こんなトリックが使える。

To insert a single bit (in the Carry) into the left or right end of the A without altering the other seven bits:

RAL Remove old left bit
RRC Insert new from Carry

“BYTE SAVING PROGRAMMING TRICKS FOR THE 8080”, Dr. Dobb’s Journal, June/July 1976, P.9



6800のRotate/Shiftは 必ずCを経由するので、同等機能を考えるのは難しい。Bを壊して良いなら、こうだ。

長くてダサいなあ。Aの操作にasla/roraは絶対必要だし、Cをどこかに保存しないといけないので、これが最短だと思う。


	rolb
	asla
	rorb
	rora


b7をcarryにコピー

符号拡張に使うために、b7をCにコピーしたい場合がある。8080には算術右シフトがないので、その準備に使う。

The right-end version is symmetrical. To divide a signed (2’s complement) number in half, it is necessary to keep the sign bit (bit 7) unchanged while shifting A right. The 8080 does not have an instruction for this, but the RAR may be used if the Carry can bet set up to match the sign bit:

RLC Copy bit 7 to Carry
RRC Restore A

“BYTE SAVING PROGRAMMING TRICKS FOR THE 8080”, Dr. Dobb’s Journal, June/July 1976, P.9

6800だと、算術右シフトがあるので、簡単。これはDDJ記事でも紹介されている。

The 6800 has a single instruction for signed right shifts, but no circular rotate. To copy a sign into the Carry:

ASR A (6800) Duplicate bit 7
ROL A Restore A with bit 7 in Carry

“BYTE SAVING PROGRAMMING TRICKS FOR THE 8080”, Dr. Dobb’s Journal, June/July 1976, P.9


Aが0でなければCを立てる/Aが0ならCを立てる

任意の条件でCを操作できると便利。A!=0 なら Cを立てる、あるいはその逆を行う。

A zero in A may be converted into either a one or a zero in the Carry (so that non-zero is the reverse) by one of the following instructions (this also works in the 6800 with appropriate opcode sub¬stitutions):

ADI 0FFH C=0 if and only if A=00
SUI 1 C=1 if and only if A=00

“BYTE SAVING PROGRAMMING TRICKS FOR THE 8080”, Dr. Dobb’s Journal, June/July 1976, P.9



記事にあるように6800でも簡単。 adda #$FF または suba #1 である。前者はnegaが短いし、後者は cmpa #1 の方が Aが壊れなくて良いかもしれない。

前者もAを壊したくなければ、nega 2回。


b7の反転をCに入れる

$80を引くだけ。$80以上ならC=0だし、$7F以下ならC=1になる。これは6800でもcmpa #$80で良い。

It is easy to get the sign of A into the Carry (any left shift will do); to get the complement of the sign is a little trickier. This instruction leaves the contents of A unchanged, and also works for the 8080:

CP! 8OH Complement bit 7 to Carry

“BYTE SAVING PROGRAMMING TRICKS FOR THE 8080”, Dr. Dobb’s Journal, June/July 1976, P.9


Bregの特定のbitを、Aregにコピーする

C言語のbit fieldを実装するときに欲しくなるやつ。単純にやると、コピー元を mask でandして、コピー先を ~mask でクリアして、両方を or する手順になる。面倒くさい。

以下の手順なら3命令だ。素晴らしい。

Assume that the data in A and B (or any other register or memory location) are already in the correct bit positions. The mask represents a byte with the ones where the data in A is to be substituted; the non-data bits of A and B may contain garbage, as they are ignored:

XRA B XOR B to A data bits
ANI Mask Delete A garbage
XRA B Insert B data

“BYTE SAVING PROGRAMMING TRICKS FOR THE 8080”, Dr. Dobb’s Journal, June/July 1976, P.9



6800にはレジスタ間論理演算命令がないので、対象はメモリになる。こんな感じ。


	eora mem
	anda #mask
	eora mem



言葉だけだとわかにくいので表も付いていた。昔の雑誌は親切だ。

“BYTE SAVING PROGRAMMING TRICKS FOR THE 8080”, Dr. Dobb’s Journal, June/July 1976, P.10

これは、実際にchibicc-6800-v1のbitfieldで使った。


; x1.a = 1;
	(中略)
; bitfieled node->ty->size=2, mem->bit_width=1, mem->bit_offset=0, codegen.c 3780
        andb #<$01
        clra
        eorb 1,x
        eora 0,x
        andb #<$01
        clra
        eorb 1,x
        eora 0,x
        stab 1,x
        staa 0,x