4ビットマイコンのDEM-/DEM+命令

4ビットマイコンのサブルーチンの中には
「DEM-」と「DEM+」という命令があるのですが、
それの「説明が足りない」というご指摘を頂きました。


▲元となったFX-マイコンのマニュアル(大人の科学マガジンwebサイトで公開中)の107ページ目。
一言しか載ってません。
今回、発売した4ビットマイコンでも説明はほとんどありません。
、、、
そこで、DEM-/DEM+命令の解説らしきものを書いておきます。
よかったら参考にしてください。
、、、(以下、解説です)、、、
DEM-命令とDEM+命令は、
10進数による足し算/引き算を行うときに使う命令です。
勝手にケタ上がり処理を行ったり、勝手にYレジスタを引いたりしまうというヘンな命令なので、FX-マイコンをよく理解している人以外には使うことをオススメしません。

4ビットマイコンでは1アドレスあたり0〜Fしか記憶できないので、
複数のアドレスに渡ってメモリに格納することによって、2ケタ以上の値を表現します。
たとえば、
50番地に「1」、51番地に「1」と入れて、「11」という数を表現することができます。
小さい番地が上位ケタ、大きい番地が下位ケタです。
もっとケタ数が欲しい場合には、52番地以降を使います。
この「11」は16進数として考えるか、10進数として考えるかで、値が変わってしまいますが、
DEM-命令とDEM+命令を扱う場合には、10進数として考えます。10進数なので、A〜Fという値は存在しません。

CAL DEM-命令は、、、

・M-Aレジスタの結果をMに代入。
・もしMがマイナス値なら(10進数で)10借りてきて、上位ケタの中身を「1」にする。
・Yレジスタから1引く。

、、、という処理を行います。「M」はデータメモリのことです。
この命令を呼ぶ前にあらかじめ、データメモリとAレジスタには値が入っていないといけません。
さらにYレジスタには計算したいケタのアドレスが入っている必要があります。


CAL DEM+命令は、、、

・M+Aレジスタの結果Mに代入。
・もしMが(10進数で)10以上なら10引いて、上位ケタに1を足す。
・Yレジスタから1引く。

、、、という処理を行います。
この命令を呼ぶ前にあらかじめ、データメモリとAレジスタには値が入っていないといけません。
さらにYレジスタには計算したいケタのアドレスが入っている必要があります。

次がDEM-の動作テスト用プログラムです。
M[50][51]=11を代入してから、6を引いて、M[51]の中身をLED表示。
結果、M[50][51]=05が入ります。15が入ります。
16進数で1-6を計算するとB(-5)となるべきところですが、DEM-命令では
存在しない上位ケタから(10進数で)10を借りてくることによってM[51]=5となります。
実行すると、7セグメントLEDには1ケタ目の「5」が表示されます。

2進LED	アドレス	記号	コード	
-------	00	TIA	8	□→Ar
------*	01	1	1	
-----*-	02	TIY	A	□→Yr
-----**	03	0	0	
----*--	04	AM	4	Ar→M
----*-*	05	TIA	8	□→Ar
----**-	06	1	1	
----***	07	TIY	A	□→Yr
---*---	08	1	1	
---*--*	09	AM	4	Ar→M
---*-*-	0A	TIA	8	□→Ar
---*-**	0B	6	6	
---**--	0C	CAL	E	実行フラグ=1ならサブルーチン実行
---**-*	0D	DEM-	E	M-Ar→M(10進補正)、Yr-1→Yr
---***-	0E	TIY	A	□→Yr
---****	0F	1	1	
--*----	10	MA	5	M→Ar
--*---*	11	AO	1	Ar→数字LED
--*--*-	12	JUMP	F	実行フラグ=1ならサブルーチン実行
--*--**	13	1	1	
--*-*--	14	2	2	


▲実行結果です。51番地の中身、11-6=「5」が出ました。ここまではいいのですが、、、

▲でも、50番地を見ると「1」になってました。
なお、
M[50][51]=01、Aレジスタ=6としても実行結果が、M[50][51]=15となりました。
上位ケタの値は見ていないようです。
ずっと勘違いしてたのですが(どうもすみません)、
この上位ケタの「1」は数値ではなくて、「ケタ下がりが発生した」というフラグの意味のようです。
なので、DEM-命令は1ケタまでしか計算できないということになります。
どうやら、
DEM+命令は自動的にケタ上がり処理をしてくれるのですが、
DEM-命令は自動的にケタ下がり処理を「しない」みたいです。

2進LED	アドレス	記号	コード	
-------	00	TIA	8	□→Ar
------*	01	0	0	
-----*-	02	TIY	A	□→Yr
-----**	03	0	0	
----*--	04	AM	4	Ar→M
----*-*	05	TIA	8	□→Ar
----**-	06	1	1	
----***	07	TIY	A	□→Yr
---*---	08	1	1	
---*--*	09	AM	4	Ar→M
---*-*-	0A	TIA	8	□→Ar
---*-**	0B	6	6	
---**--	0C	CAL	E	実行フラグ=1ならサブルーチン実行
---**-*	0D	DEM-	E	M-Ar→M(10進補正)、Yr-1→Yr
---***-	0E	TIY	A	□→Yr
---****	0F	1	1	
--*----	10	MA	5	M→Ar
--*---*	11	AO	1	Ar→数字LED
--*--*-	12	JUMP	F	実行フラグ=1ならサブルーチン実行
--*--**	13	1	1	
--*-*--	14	2	2	

▲DEM-命令の(おそらく)正しい使い方です。
M[50][51]=01を代入してから、6を引いて、M[51]の中身をLED表示します。


▲元となったFX-マイコンのマニュアル(大人の科学マガジンwebサイトで公開中)の115ページ目。
サンプルのフローチャートをよく見ると、1を代入するって書かれてますね。てっきり誤植かと思っていたのですが、これで合ってます。
こんなの気付くか!?って感じですけど。
、、、
そして、
次がCAL DEM+の動作テスト用プログラムです。
M[50][51]=09を代入してから、2を足して、M[51]の中身をLED表示。
結果、M[50][51]=11が入ります。
16進数だと9+2=Bとなるべきところですが、DEM+命令を使うと11となります。
ケタ上がりが発生するので、上位ケタのM[50]は1加算されて1となり、下位ケタのM[51]には1が残ります。
実行すると、7セグメントLEDには1ケタ目の「1」が表示されます。

2進LED	アドレス	記号	コード	
-------	00	TIA	8	□→Ar
------*	01	0	0	
-----*-	02	TIY	A	□→Yr
-----**	03	0	0	
----*--	04	AM	4	Ar→M
----*-*	05	TIA	8	□→Ar
----**-	06	9	9	
----***	07	TIY	A	□→Yr
---*---	08	1	1	
---*--*	09	AM	4	Ar→M
---*-*-	0A	TIA	8	□→Ar
---*-**	0B	2	2	
---**--	0C	CAL	E	実行フラグ=1ならサブルーチン実行
---**-*	0D	DEM+	F	M+Ar→M(10進補正)、Yr-1→Yr
---***-	0E	TIY	A	□→Yr
---****	0F	1	1	
--*----	10	MA	5	M→Ar
--*---*	11	AO	1	Ar→数字LED
--*--*-	12	JUMP	F	実行フラグ=1ならサブルーチン実行
--*--**	13	1	1	
--*-*--	14	2	2	

、、、
さらに応用編。
M[50][51][52]=999を代入してから、DEM+命令で1を足して、1桁目の中身をLED表示するプログラムです。

2進LED	アドレス	記号	コード	
-------	00	TIA	8	□→Ar
------*	01	9	9	
-----*-	02	TIY	A	□→Yr
-----**	03	0	0	
----*--	04	AM	4	Ar→M
----*-*	05	TIA	8	□→Ar
----**-	06	9	9	
----***	07	TIY	A	□→Yr
---*---	08	1	1	
---*--*	09	AM	4	Ar→M
---*-*-	0A	TIA	8	□→Ar
---*-**	0B	9	9	
---**--	0C	TIY	A	□→Yr
---**-*	0D	2	2	
---***-	0E	AM	4	Ar→M
---****	0F	TIA	8	□→Ar
--*----	10	1	1	
--*---*	11	CAL	E	実行フラグ=1ならサブルーチン実行
--*--*-	12	DEM+	F	M+Ar→M(10進補正)、Yr-1→Yr
--*--**	13	TIY	A	□→Yr
--*-*--	14	1	1	
--*-*-*	15	MA	5	M→Ar
--*-**-	16	AO	1	Ar→数字LED
--*-***	17	JUMP	F	実行フラグ=1なら□□→PC
--**---	18	1	1	
--**--*	19	7	7	


▲実行結果。999+1なので、0が表示されました。


▲DEM+命令では、連鎖的に桁上がり処理が行われます。なので、50〜51番地には0が入りました。ここまではいいのですが、、、


▲50番地を+1したあとケタ上がりは終わらず、メモリ内を一周して5F番地が+1されてしますようです。それでさらに連鎖的にケタ上がりが起きて、最終的に52番地に1加算され53〜5F番地に6が入ってしまいました(写真はFX-マイコンシミュレータ)。
元々、53〜5F番地にはFが入っていたので、
F+1=(10進数で)10+6ということで6になったようです。
つまり、最上位ケタをケタ上がりさせるとメモリが壊れるということになります。
DEM+命令を使う場合にはご注意ください。