10進表示

目次

概要

Z80基本

BCD命令ひたすら引き算

6502基本

ひたすら引き算

速度判定


6502基本



	LDA #>8086 ; 2
	STA >0 ; 3
	LDA #<8086 ; 2
	STA >1 ; 3
	LDA #0 ; 2
	PHA ; 3

LOOP:
	LDA #10 ; 2
	JSR DIV ; 6 + 400
	ORA #$30 ; 2
	PHA ; 3
	LDA >0 ; 3
	ORA >1 ; 3
	BNE LOOP ; 3 / 2

	LDX #-1 ; 2

AFTER:
	INX ; 2
	PLA ; 4
	STA DECIMAL,X ; 5
	BNE AFTER ; 3 / 2
END:

6502 では、素直にスタックを使用しています。

教科書に乗ってそうなプログラムで、特に説明はいらないかな…


前処理に 15 クロック。

1桁の処理に 22 クロック。


最後は1クロック速くなり、次の処理のために 2 クロックかかります。

つまり、最後は +1 クロック。


後処理に、1桁ごとに 14+400 クロック。400 は除算ルーチンです。

これも最後は 1 クロック速くなります。


15 + 22*4 +1 +414*4 -1 = 1759


総計は 1759 クロックになります。


ひたすら引き算

2014.9.5 追記

「ひたすら引き算する」方法によるプログラム、6502 版も投稿されました。ありがとうございます。



	LDY #0 ;2
	LDX #<8086 ;2
	STX >1 ;3
	LDA #>8086 ;2
	CPX #<10000 ;2
	BCC CHK1000 ;3/2
	BNE L10000 ;3/2
	CMP #>10000 ;2
	BCS L10000 ;3/2
CHK1000:
	CPX #<1000 ;2
	BCC CHK256 ;3/2
	BNE L1000 ;3/2
	CMP #>1000 ;2
	BCS L1000 ;3/2
CHK256:
	CPX #1 ;2
	BCS L100 ;3/2
	CMP #100 ;2
	BCS L100 ;3/2
	CMP #10 ;2
	BCS L10 ;3/2
	ORA #$30 ;2
	STA DECIMAL ;4
	BNE LAST ;3

SUB16:
	STX >2 ;3
	LDX #$30 ;2
	BNE SSKIP ;3
SLOOP:
	STA >1 ;3
	INX ;2
	LDA >0 ;3
SSKIP:
	SBC >2 ;3
	STA >0 ;3
	LDA >1 ;3
	SBC >3 ;3
	BCS SLOOP ;3/2
	TXA ;2
	STA DECIMAL,Y ;5
	INY ;2
	LDA >0 ;3
	ADC >2 ;3
	SEC ;2
	RTS ;6

L10000:
	LDX #<10000 ;2
	STX >3 ;3
	LDX #>10000 ;2
	JSR SUB16 ;6
L1000:
	LDX #<1000 ;2
	STX >3 ;3
	LDX #>1000 ;2
	JSR SUB16 ;6
L100:
	LDX #<100 ;2
	STX >3 ;3
	LDX #>100 ;2
	JSR SUB16 ;6
L10:
	LDX #$30-1 ;2
LOOP:
	INX ;2
	SBC #10 ;2
	BCS LOOP ;3/2
	ADC #10+$30 ;2
	STA DECIMAL+1,Y ;5
	TXA ;2
	STA DECIMAL,Y ;5
	INY ;2
LAST:
	LDA #0 ;2
	STA DECIMAL+1,Y ;5

基本的にはZ80からの移植です。

が、もちろん 6502 に特化して高速化している個所はあります。


>0 >1 に被除数を入れているのですが、基本的には被乗数の下位バイトは A に入っていて、>0 は退避用です。

また、前処理の間は上位バイトは X に入っていて、メモリアクセスを出来るだけ少なくしています。


SUB16 ルーチンは、Z80 と違い、16bit 演算ができないため、繰り上がりながら 8bit 演算を繰り返しています。

これは 6502 のお約束。


8bit 演算に収まる 10の位だけは、SUB16 を呼び出さずに計算します。これも Z80 と同じ。


処理速度ですが、非常に厄介なことになります。


Z80版と同じく、条件分岐が多いからひたすら数えるしかない…と言うのは同じなのですが、分岐の形が違うため、非常に多くの「場合わけ」が存在してしまうのですね。


Z80 なら、10000 と比較することで、5桁かどうかわかりました。

でも、6502 は 8bit 演算しかできないので、10000 と比較できません。

上位バイトの比較だけで明らかになる場合と、下位バイトまで比較しないと明らかにならない場合の2通りの速度があります。


これは、「5桁じゃない」と判るのも2通りの速度がある、と言う意味にもなります。

5桁でないなら4桁か? ここでも、処理に入る前に2通りの経路があり、4桁判定に2通りの経路があるため、組み合わせとして4経路。

3桁の場合は8経路… というわけで、クロック数の組み合わせはどんどん増えます。表にしても無意味なくらいに。


というわけで、ここでは Z80 のような速度表を示さず、ただ数えた結果だけを書きます。


8086 を 10 進数に直す場合、何桁の数値かを判定する前処理で 21 クロック。


16bit 演算ルーチンは、数値が n の桁の計算を終了するのに、23*n + 45 クロック。

上位2桁はこのルーチンで計算され、計 274 クロックかかります。


10の位は別のループで計算していて、7*(n+1)-1 クロック。

n=8 で計算することになるので、62 クロックかかります。


それ以外の部分は、4桁の計算の際に限ると、全部で 51 クロック。


21+274+62+51 = 408


総計は 408 クロックになります。


次ページ: 速度判定


前ページ 1 2 3 4 次ページ

(ページ作成 2014-08-28)
(最終更新 2014-09-06)
第2版 …他の版 初版

前記事:割り算     戻る
トップページへ

-- share --

2000

-- follow --




- Reverse Link -