標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第258回]

●INR、DCRのテストプログラムです

MOV命令の次はINR、DCR命令のテストです。
3本目のテストプログラムです。
INR r、DCR rだけではなくて、INR M、DCR Mもテストします。

テストプログラムのリストです。


2009/6/12  7:40  TEST3.TXT
END=40E5
              ;;; MYCPU80 TEST3
              ;;; INR DCR
              ;;; 09/6/11 6/12
              ;
                ORG $4000
              ;
                STCK=$5000
                ERBF=$6000
              ;
4000 310050     LXI SP,STCK
4003 0E00       MVI C,00
4005 C5         PUSH B
4006 F1         POP PSW;CLEAR FLAG REGISTER
              ; 
              ; INR M   DCR M
4007 210050     LXI H,STCK
400A 2B         DCX H
400B 36FE       MVI M,FE
400D 2B         DCX H
400E F9         SPHL
400F 23         INX H
4010 0604       MVI B,04
4012 34       LOOP1:INR M
4013 7E         MOV A,M
4014 F5         PUSH PSW
4015 05         DCR B
4016 C21240     JNZ LOOP1
4019 4E         MOV C,M
401A 2B         DCX H
401B 71         MOV M,C
401C 0604       MVI B,04
401E 35       LOOP2:DCR M
401F 7E         MOV A,M
4020 F5         PUSH PSW
4021 05         DCR B
4022 C21E40     JNZ LOOP2
              ;INR r
4025 0E00       MVI C,00
4027 C5         PUSH B
4028 F1         POP PSW;CLEAR FLAG REGISTER
4029 06FE       MVI B,FE
402B 04         INR B
402C 78         MOV A,B
402D F5         PUSH PSW
402E 48         MOV C,B
402F 0C         INR C
4030 79         MOV A,C
4031 F5         PUSH PSW
4032 51         MOV D,C
4033 14         INR D
4034 7A         MOV A,D
4035 F5         PUSH PSW
4036 5A         MOV E,D
4037 1C         INR E
4038 7B         MOV A,E
4039 F5         PUSH PSW
403A 63         MOV H,E
403B 24         INR H
403C 7C         MOV A,H
403D F5         PUSH PSW
403E 6C         MOV L,H
403F 2C         INR L
4040 7D         MOV A,L
4041 F5         PUSH PSW
4042 7D         MOV A,L
4043 3C         INR A
4044 F5         PUSH PSW
4045 C5         PUSH B
4046 D5         PUSH D
4047 E5         PUSH H
              ;DCR r
4048 47         MOV B,A
4049 1E00       MVI E,00
404B 1600       MVI D,00
404D D5         PUSH D
404E F1         POP PSW;CLEAR FLAG&A REGISTER
404F 05         DCR B
4050 78         MOV A,B
4051 F5         PUSH PSW
4052 48         MOV C,B
4053 0D         DCR C
4054 79         MOV A,C
4055 F5         PUSH PSW
4056 51         MOV D,C
4057 15         DCR D
4058 7A         MOV A,D
4059 F5         PUSH PSW
405A 5A         MOV E,D
405B 1D         DCR E
405C 7B         MOV A,E
405D F5         PUSH PSW
405E 63         MOV H,E
405F 25         DCR H
4060 7C         MOV A,H
4061 F5         PUSH PSW
4062 6C         MOV L,H
4063 2D         DCR L
4064 7D         MOV A,L
4065 F5         PUSH PSW
4066 7D         MOV A,L
4067 3D         DCR A
4068 F5         PUSH PSW
4069 C5         PUSH B
406A D5         PUSH D
406B E5         PUSH H
              ;;;
              ; CHECK
              ;INR M  DCR M
              ;
406C 310060     LXI SP,ERBF
406F 210050     LXI H,STCK
4072 2B         DCX H
4073 11BD40     LXI D,TBL1END
4076 0612       MVI B,12;=18
4078 1A       CKLP1:LDAX D
4079 BE         CMP M
407A CA7E40     JZ CKLP1_2
407D E5         PUSH H;ERR
407E 2B       CKLP1_2:DCX H
407F 1B         DCX D
4080 05         DCR B
4081 C27840     JNZ CKLP1
              ;INR r
4084 11D140     LXI D,TBL2END
4087 0614       MVI B,14;=20
4089 1A       CKLP2:LDAX D
408A BE         CMP M
408B CA8F40     JZ CKLP2_2
408E E5         PUSH H;ERR
408F 2B       CKLP2_2:DCX H
4090 1B         DCX D
4091 05         DCR B
4092 C28940     JNZ CKLP2
              ;DCR r
4095 11E540     LXI D,TBL3END
4098 0614       MVI B,14;=20
409A 1A       CKLP3:LDAX D
409B BE         CMP M
409C CAA040     JZ CKLP3_2
409F E5         PUSH H;ERR
40A0 2B       CKLP3_2:DCX H
40A1 1B         DCX D
40A2 05         DCR B
40A3 C29A40     JNZ CKLP3
                ;
40A6 E5         PUSH H
40A7 210000     LXI H,$0000
40AA E5         PUSH H
40AB 76         HLT
              ;
              ;COMPARE DATA TABLE
              ;INR M  DCR M
40AC 80       TBL1:DB 80
40AD FE         DB FE
40AE 94         DB 94
40AF FF         DB FF
40B0 44         DB 44
40B1 00         DB 00
40B2 00         DB 00
40B3 01         DB 01
40B4 00         DB 00
40B5 02         DB 02
40B6 00         DB 00
40B7 01         DB 01
40B8 54         DB 54
40B9 00         DB 00
40BA 84         DB 84
40BB FF         DB FF
40BC FE         DB FE;DCR M
40BD 02       TBL1END:DB 02;INR M
              ;INR r
40BE 04         DB 04;L
40BF 03         DB 03;H
40C0 02         DB 02;E
40C1 01         DB 01;D
40C2 00         DB 00;C
40C3 FF         DB FF;B
40C4 04         DB 04;F
40C5 05         DB 05;A
40C6 00         DB 00
40C7 04         DB 04
40C8 04         DB 04
40C9 03         DB 03
40CA 00         DB 00
40CB 02         DB 02
40CC 00         DB 00
40CD 01         DB 01
40CE 54         DB 54
40CF 00         DB 00
40D0 84         DB 84
40D1 FF       TBL2END:DB FF
              ;DCR r
40D2 FF         DB FF;L
40D3 00         DB 00;H
40D4 01         DB 01;E
40D5 02         DB 02;D
40D6 03         DB 03;C
40D7 04         DB 04;B
40D8 80         DB 80;F
40D9 FE         DB FE;A
40DA 94         DB 94
40DB FF         DB FF
40DC 44         DB 44
40DD 00         DB 00
40DE 00         DB 00
40DF 01         DB 01
40E0 00         DB 00
40E1 02         DB 02
40E2 04         DB 04
40E3 03         DB 03
40E4 00         DB 00
40E5 04       TBL3END:DB 04
              ;
CKLP1        =4078  CKLP1_2      =407E  CKLP2        =4089  
CKLP2_2      =408F  CKLP3        =409A  CKLP3_2      =40A0  
ERBF         =6000  LOOP1        =4012  LOOP2        =401E  
STCK         =5000  TBL1         =40AC  TBL1END      =40BD  
TBL2END      =40D1  TBL3END      =40E5  

実行した結果の値は、またUSB経由でパソコンに送信しました。


前回、前々回のTEST2、TEST1と同じで、結果の値がスタックに入れられる順番と、比較データのテーブルの並び順が入れ替わっています。
比較するデータのテーブルを、結果の値の並び順と同じにするには、@40D2〜40E5A40BE〜40D1B40AC〜40BDの順にします。
そのように並べ替えて比較してみると、全ての結果があらかじめ用意したデータと一致していることがわかります。

しかし、ただそのように書いただけでは、ふーん、そうなの、で終わってしまいそうです。
このプログラムは説明が必要です。
いったい何をやっているのでしょう。

●INR M、DCR Mのテスト

まず、最初はINR M、DCR Mのテストです。
あとでチェックができるように、INR Mのためには、スタックトップの4FFFを、そしてDCR M用にはその次の4FFEを使います。
最初に4FFFをHLに入れて(つまりMのアドレスは4FFFになります)、そこに初期値FEを入れます(4007〜400C)。

前回のMOV、MVI命令はフラグが変化しない命令でしたが、INR、DCR命令はフラグが変化します。
ですから結果の値を確認するとともに、フラグの変化も確認する必要があります。
初期値としてFEのような変な値を選んだのはそのためです。
INR命令を繰り返し実行することによって、Mの値はFE→FF→00→01→02のように変化します。
値の変化とともにフラグも変化します。
主要なフラグであるS(サイン)フラグとZ(ゼロ)フラグの変化が確認できるように、ということでその値を選びました。

INR Mを4回繰り返し実行するごとに、MOV A,Mで結果をAレジスタに入れたうえでフラグと一緒にスタックに保存します(400D〜4018)。

HLを−1してFFFEをMのアドレスにしたうえで、最後の結果の値の02を、新しいMに入れます(4019〜401B)。

今度はDCR Mを4回繰り返します。
結果の値は、02→01→00→FF→FEと変化します。
これもINR Mと同じように、Aレジスタに入れたうえでフラグとともにスタックに保存します(401C〜4024)。

スタックは4FFFから前に向かって消費されていきます。
ですから命令が実行された順に結果の記録を確認しようとすると、スタックを後ろから見ていくことになります。

パソコン画面の下の方、USB経由で受信した結果の値は、一番最後がアドレス4FFFになっています。
そこから逆に見ていきます。
一番最後は02です。
ここはINR M命令でMとして使ったアドレスです。
FEから始まって、4回INR Mを繰り返しましたから、結果は02です。

その前はFEになっています。
ここはDCR M命令でMとして使ったアドレスです。
02から始まって4回DCR Mを繰り返しましたから、結果はFEです。

その前から8バイトはINR Mを1回実行するごとに、結果の値とフラグを保存したところです。
10020001540084FF の8バイトです。←誤記があります(訂正 00020001540084FF)
さらにそこから前の8バイトはDCR Mを1回実行するごとに、結果の値とフラグを保存したところです。
80FE94FF4400000  の8バイトです。←誤記があります(訂正 80FE94FF44000001)

84FFは84がフラグでFFが結果の値です。
FFは負数なのでS(サイン)フラグがONになっています。

その前の5400は54がフラグで00が結果の値です。
Z(ゼロ)フラグとH(ハーフキャリー)フラグがONになっています。
INR、DCR命令では、C(キャリー)フラグは変化しません。

●8080のフラグ

フラグについては[第59回]で説明しています。
でももうずいぶん時間が経ってしまいましたから、参考までに、フラグレジスタの中の各フラグのビット位置を下に示します。
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
S Z - H - P - C

この連載記事を最初からずっとお読みいただいている方で、なお私と違って記憶力のよろしい方の中には、ここまでお読みいただいて、あれぇ?とお思いになられた方もいらっしゃるかもしれません。

ええ。
じつは、そうなんです。
でも、それについては、もう少しあとでお話をするつもりですから、今は、このままということで。


●INR rのテスト

4025〜4047のプログラムはINR rのテストです。
基本的にはINR Mのテストと同じです。
最初にBレジスタにFFを入れて、INR Bを実行します。
結果の値をAレジスタに入れて、フラグとともにスタックに保存します。
次に同じ結果の値をCレジスタに入れて、今度はINR Cを実行します。
このようにB→C→D→E→H→L→Aの順にINR rを実行しながら結果の値とフラグをスタックに保存していきます。
最後にPUSH B、PUSH D、PUSH Hで各レジスタの値も保存します。

結果の値は、
0403 0201 00FF 0405 0004 0403 0002 0001 5400 84FFの部分です。
分かり易くするために2バイトずつに区切ってみました。
実行された結果は、後ろから前に向かっていく順で保存されています。一番後ろのFFがINR Bの結果の値で84がフラグです。
一番前の0403は一番最後に実行されたPUSH Hによって保存された、Lレジスタの値(04)とHレジスタの値(03)です。

●DCR rのテスト

4048〜406BのプログラムはDCR rのテストです。
基本的にはDCR Mのテストと同じです。
INRのテストでの最後の値はAレジスタの05です。
その05をBレジスタに入れてDCR Bの実行から開始します。
最初にBレジスタに05を入れて、INR Bを実行します。
結果の値をAレジスタに入れて、フラグとともにスタックに保存します。
次に同じ結果の値をCレジスタに入れて、DCR Cを実行します。
このようにB→C→D→E→H→L→Aの順にDCR rを実行しながら結果の値とフラグをスタックに保存していきます。
最後にPUSH B、PUSH D、PUSH Hで各レジスタの値も保存します。

結果の値は、
FF00 0102 0304 80FE 94FF 4400 0001 0002 0403 0004の部分です。
さきほどと同じように2バイトずつに区切りました。
実行された結果は、後ろから前に向かっていく順で保存されています。一番後ろの04がDCR Bの結果の値で00がフラグです。
一番前のFF00は一番最後に実行されたPUSH Hによって保存された、Lレジスタの値(FF)とHレジスタの値(00)です。
2009.6.24upload
2011.5.1誤記訂正

前へ
次へ
ホームページトップへ戻る