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

●JMP、CALL、RET、PCHLのテストプログラムです

9本目のテストプログラムです。
今回はJMP、CALL、RET命令のテストプログラムです。
PCHLもJMP命令の仲間のようなものですから、ついでにテストしてしまいます。

いままでにテストした命令は、レジスタに対して計算をするとか、値を入れるとかというような、計算処理的なものでした。
ですから計算結果とフラグを保存しておいて、あとでそれをチェックすればよかったのですが、今回のJMP、CALL、RETはいずれもプログラムの流れを変更する命令です。
さて、どのようにテストしたらよいものか、ちょいと悩んでしまいました。
しかもただのJMP、CALL、RETではなくて、そのいずれもが、JNZ、CZのように、NZ、Z、NC、C、M、P、PE、PO、の条件付の命令を含んでいます。
これはなかなかにやっかいです。

プログラムの流れを変える命令ですから、プログラムが実行されていく過程をひとつひとつ、いわばトレース機能のように記録していくことができれば、あとでその結果を検証することで、命令が正しく実行されたかどうかを確認することができます。

という考え方でプログラムを作りました。
あまり一般的ではありません。かなりクセのあるプログラムになっています。


2009/6/18  9:12  TEST9.TXT
END=42F6
              ;;; MYCPU80 TEST9
              ;;; JMP CALL RET PCHL
              ;;; 09/6/16 6/18
              ;
                ORG $4100
              ;
                STCK=$5000
                ERBF=$6000
              ;
4100 310050     LXI SP,STCK
4103 0E00       MVI C,00
4105 C5         PUSH B
4106 F1         POP PSW;CLEAR FLAG REGISTER
              ; 
              ; JMP
4107 CD1F42     CALL PSH
410A DA2242     JC JMK
410D CD1F42     CALL PSH
4110 D22242     JNC JMK
4113 CD1F42     CALL PSH
4116 CA2242     JZ JMK
4119 CD1F42     CALL PSH
411C C22242     JNZ JMK
411F CD1F42     CALL PSH
4122 F22242     JP JMK
4125 CD1F42     CALL PSH
4128 FA2242     JM JMK
412B CD1F42     CALL PSH
412E EA2242     JPE JMK
4131 CD1F42     CALL PSH
4134 E22242     JPO JMK
              ;CALL
4137 CD1F42     CALL PSH
413A DC1F42     CC PSH
413D CD1F42     CALL PSH
4140 D41F42     CNC PSH
4143 CD1F42     CALL PSH
4146 CC1F42     CZ PSH
4149 CD1F42     CALL PSH
414C C41F42     CNZ PSH
414F CD1F42     CALL PSH
4152 F41F42     CP PSH
4155 CD1F42     CALL PSH
4158 FC1F42     CM PSH
415B CD1F42     CALL PSH
415E EC1F42     CPE PSH
4161 CD1F42     CALL PSH
4164 E41F42     CPO PSH
              ;RET
4167 110000     LXI D,$0000
416A CD2742     CALL RC
416D CD3142     CALL RNC
4170 CD3B42     CALL RZ
4173 CD4542     CALL RNZ
4176 CD4F42     CALL RP
4179 CD5942     CALL RM
417C CD6342     CALL RPE
417F CD6D42     CALL RPO
              ;
4182 0EFF       MVI C,FF
4184 C5         PUSH B
4185 F1         POP PSW;SET FLAG REGISTER
              ; 
              ; JMP
4186 CD1F42     CALL PSH
4189 DA2242     JC JMK
418C CD1F42     CALL PSH
418F D22242     JNC JMK
4192 CD1F42     CALL PSH
4195 CA2242     JZ JMK
4198 CD1F42     CALL PSH
419B C22242     JNZ JMK
419E CD1F42     CALL PSH
41A1 F22242     JP JMK
41A4 CD1F42     CALL PSH
41A7 FA2242     JM JMK
41AA CD1F42     CALL PSH
41AD EA2242     JPE JMK
41B0 CD1F42     CALL PSH
41B3 E22242     JPO JMK
              ;CALL
41B6 CD1F42     CALL PSH
41B9 DC1F42     CC PSH
41BC CD1F42     CALL PSH
41BF D41F42     CNC PSH
41C2 CD1F42     CALL PSH
41C5 CC1F42     CZ PSH
41C8 CD1F42     CALL PSH
41CB C41F42     CNZ PSH
41CE CD1F42     CALL PSH
41D1 F41F42     CP PSH
41D4 CD1F42     CALL PSH
41D7 FC1F42     CM PSH
41DA CD1F42     CALL PSH
41DD EC1F42     CPE PSH
41E0 CD1F42     CALL PSH
41E3 E41F42     CPO PSH
              ;RET
41E6 110000     LXI D,$0000
41E9 CD2742     CALL RC
41EC CD3142     CALL RNC
41EF CD3B42     CALL RZ
41F2 CD4542     CALL RNZ
41F5 CD4F42     CALL RP
41F8 CD5942     CALL RM
41FB CD6342     CALL RPE
41FE CD6D42     CALL RPO
              ;
              ; CHECK
4201 310060     LXI SP,ERBF
4204 210050     LXI H,STCK
4207 2B         DCX H
4208 11F642     LXI D,TBL1END
420B 0680       MVI B,80
420D 1A       LOOP0:LDAX D
420E BE         CMP M
420F CA1342     JZ LOOP0_2
4212 E5         PUSH H;ERR
4213 2B       LOOP0_2:DCX H
4214 1B         DCX D
4215 05         DCR B
4216 C20D42     JNZ LOOP0
4219 E5         PUSH H
421A 210000     LXI H,$0000
421D E5         PUSH H
421E 76         HLT
              ;
              ;SUBROUTINE
              ;
421F E1       PSH:POP H
4220 E5         PUSH H
4221 E9         PCHL
              ;
4222 23       JMK:INX H
4223 23         INX H
4224 23         INX H
4225 E5         PUSH H
4226 E9         PCHL
              ;
4227 E1       RC:POP H
4228 13         INX D
4229 D5         PUSH D
422A E5         PUSH H
422B D8         RC
422C E1         POP H
422D D1         POP D
422E 13         INX D
422F D5         PUSH D
4230 E9         PCHL
              ;
4231 E1       RNC:POP H
4232 13         INX D
4233 D5         PUSH D
4234 E5         PUSH H
4235 D0         RNC
4236 E1         POP H
4237 D1         POP D
4238 13         INX D
4239 D5         PUSH D
423A E9         PCHL
              ;
423B E1       RZ:POP H
423C 13         INX D
423D D5         PUSH D
423E E5         PUSH H
423F C8         RZ
4240 E1         POP H
4241 D1         POP D
4242 13         INX D
4243 D5         PUSH D
4244 E9         PCHL
              ;
4245 E1       RNZ:POP H
4246 13         INX D
4247 D5         PUSH D
4248 E5         PUSH H
4249 C0         RNZ
424A E1         POP H
424B D1         POP D
424C 13         INX D
424D D5         PUSH D
424E E9         PCHL
              ;
424F E1       RP:POP H
4250 13         INX D
4251 D5         PUSH D
4252 E5         PUSH H
4253 F0         RP
4254 E1         POP H
4255 D1         POP D
4256 13         INX D
4257 D5         PUSH D
4258 E9         PCHL
              ;
4259 E1       RM:POP H
425A 13         INX D
425B D5         PUSH D
425C E5         PUSH H
425D F8         RM
425E E1         POP H
425F D1         POP D
4260 13         INX D
4261 D5         PUSH D
4262 E9         PCHL
              ;
4263 E1       RPE:POP H
4264 13         INX D
4265 D5         PUSH D
4266 E5         PUSH H
4267 E8         RPE
4268 E1         POP H
4269 D1         POP D
426A 13         INX D
426B D5         PUSH D
426C E9         PCHL
              ;
426D E1       RPO:POP H
426E 13         INX D
426F D5         PUSH D
4270 E5         PUSH H
4271 E0         RPO
4272 E1         POP H
4273 D1         POP D
4274 13         INX D
4275 D5         PUSH D
4276 E9         PCHL
              ;;;
              ;
              ;COMPARE DATA TABLE
              ;
              ; RC-RPO FLAG=1
4277 0C         DB 0C
4278 00         DB 00
4279 0A         DB 0A
427A 00         DB 00
427B 09         DB 09
427C 00         DB 00
427D 08         DB 08
427E 00         DB 00
427F 06         DB 06
4280 00         DB 00
4281 04         DB 04
4282 00         DB 00
4283 03         DB 03
4284 00         DB 00
4285 01         DB 01
4286 00         DB 00
              ;CC-CPO FLAG=1
4287 E3         DB E3
4288 41         DB 41
4289 E0         DB E0
428A 41         DB 41
428B DD         DB DD
428C 41         DB 41
428D DA         DB DA
428E 41         DB 41
428F D7         DB D7
4290 41         DB 41
4291 D1         DB D1
4292 41         DB 41
4293 CB         DB CB
4294 41         DB 41
4295 C8         DB C8
4296 41         DB 41
4297 C5         DB C5
4298 41         DB 41
4299 BF         DB BF
429A 41         DB 41
429B BC         DB BC
429C 41         DB 41
429D B9         DB B9
429E 41         DB 41
429F B3         DB B3
42A0 41         DB 41
42A1 B0         DB B0
42A2 41         DB 41
42A3 AD         DB AD
42A4 41         DB 41
42A5 AA         DB AA
42A6 41         DB 41
              ;JC-JPO FLAG=1
42A7 A7         DB A7
42A8 41         DB 41
42A9 A1         DB A1
42AA 41         DB 41
42AB 9B         DB 9B
42AC 41         DB 41
42AD 98         DB 98
42AE 41         DB 41
42AF 95         DB 95
42B0 41         DB 41
42B1 8F         DB 8F
42B2 41         DB 41
42B3 8C         DB 8C
42B4 41         DB 41
42B5 89         DB 89
42B6 41         DB 41
              ;RC-RPO FLAG=0
42B7 0C         DB 0C
42B8 00         DB 00
42B9 0B         DB 0B
42BA 00         DB 00
42BB 09         DB 09
42BC 00         DB 00
42BD 07         DB 07
42BE 00         DB 00
42BF 06         DB 06
42C0 00         DB 00
42C1 05         DB 05
42C2 00         DB 00
42C3 03         DB 03
42C4 00         DB 00
42C5 02         DB 02
42C6 00         DB 00
              ;CC-CPO FLAG=0
42C7 67         DB 67
42C8 41         DB 41
42C9 64         DB 64
42CA 41         DB 41
42CB 5E         DB 5E
42CC 41         DB 41
42CD 58         DB 58
42CE 41         DB 41
42CF 55         DB 55
42D0 41         DB 41
42D1 52         DB 52
42D2 41         DB 41
42D3 4F         DB 4F
42D4 41         DB 41
42D5 4C         DB 4C
42D6 41         DB 41
42D7 46         DB 46
42D8 41         DB 41
42D9 43         DB 43
42DA 41         DB 41
42DB 40         DB 40
42DC 41         DB 41
42DD 3A         DB 3A
42DE 41         DB 41
42DF 37         DB 37
42E0 41         DB 41
42E1 34         DB 34
42E2 41         DB 41
42E3 2E         DB 2E
42E4 41         DB 41
42E5 28         DB 28
42E6 41         DB 41
              ;JC-JPO FLAG=0
42E7 25         DB 25
42E8 41         DB 41
42E9 22         DB 22
42EA 41         DB 41
42EB 1F         DB 1F
42EC 41         DB 41
42ED 1C         DB 1C
42EE 41         DB 41
42EF 16         DB 16
42F0 41         DB 41
42F1 13         DB 13
42F2 41         DB 41
42F3 10         DB 10
42F4 41         DB 41
42F5 0A         DB 0A
42F6 41       TBL1END:DB 41
              ;
ERBF         =6000  JMK          =4222  LOOP0        =420D  
LOOP0_2      =4213  PSH          =421F  RC           =4227  
RM           =4259  RNC          =4231  RNZ          =4245  
RP           =424F  RPE          =4263  RPO          =426D  
RZ           =423B  STCK         =5000  TBL1END      =42F6  

あとで見直してみましたら、条件なしのJMP命令とRET命令はテストしていませんでした。
でも、JMPやRETはTK80モニタプログラムの中でも繰り返し出てきていますから、まあこれについては、あらためてテストしなくてもよいでしょう(汎用のテストプログラムを作ることが目的ではありませんから、そういうことにしてしまいましょう)。
条件なしのCALL命令については、今回のテストプログラムの中でも繰り返し使っていますから、これもついでにテストができてしまったことになります。

ということで、条件付きのJMP、CALL、RET命令をテストしますが、いちいち条件を設定するのは面倒ですから、最初に全てのフラグをクリアした状態で各命令をテストし、そのあとで今度はすべてのフラグをセットした状態で、同じ命令をテストすることにします。

最初は条件JMP命令です。
CALL PSHとJMKへの条件JMP命令の繰り返しです。
PSHとJMKルーチンは後ろの方のSUBROUTINEのところにあります。


421F E1       PSH:POP H
4220 E5         PUSH H
4221 E9         PCHL
              ;
4222 23       JMK:INX H
4223 23         INX H
4224 23         INX H
4225 E5         PUSH H
4226 E9         PCHL
              ;

PSHは何をしているのでしょう。
実はCALL PSH命令の次のアドレスをスタックに保存しているのです。
CALL命令を実行すると、その次のアドレスがスタックに保存されますが、それはRET命令を使うことでプログラムカウンタに入れられてしまって、スタックには残りません。
そこでRETを使わないで、PCHLで「戻る」ことによって、スタックに戻り先のアドレスをわざと残したままにしているのです。

JMP命令はCALL命令と違って、その次のアドレスをスタックに入れたりはしません。
そこで上のPSHと同じ目的をJMP命令で実現できるように、ということでJMKルーチンを作りました。

CALL PSHとJX JMKとを交互に使うことで、あとでスタックに残ったアドレスを見れば、どの条件JMP命令が実行され、どの条件JMP命令がパスされたのかがわかります。

次の条件CALL命令のテストも、条件JMP命令のテストと同じことをしています。
CALL PSHとCX PSHを交互に使うことで、あとでスタックに残ったアドレスを見れば、どの条件CALL命令が実行され、どの条件CALL命令がパスされたのかがわかります。

RET命令については、JMP命令やCALL命令のようにすることはできません。
なにしろ”RETERN”しなければいけないのですから。
そこでサブルーチンの中で条件RET命令を使います。
それが使われたのかパスされたのかが後でわかるようにDEレジスタをカウンタに使います。
RX命令の前後でINX D命令でカウントアップすることで、どの条件RET命令が実行され、どの条件JMP命令がパスされたのかがわかります。

なぜINX命令かといいますと、もしここでINR命令を使うと、それによってフラグが変化してしまうので、テストにならないからです(前回のテストの顛末を思い出してください)。
INX命令がフラグを変化させないことにもそれなりの意図があったのではないか、と思います。

いつものように結果をUSB経由でパソコンに送りました。

これが結果のデータであることはわかったとしても、それが正しい結果なのかどうかを確認するのは、なかなかに大変です。
でもすでに説明しましたように、あらかじめZBKボードの上で、Z80によって同じプログラムを実行させて、その結果をもとにして比較データを作っていますから、比較した結果が一致していれば、正しく実行されたことになります。

参考までに、ZBKボードで実行した結果を表示した画面です。


ここのところ、ソフトウェア(プログラム)のお話ばかりが続いています。
ちょいと退屈かもしれません。
でも、でも、ちょいと考えてみてくださいな。

こうしてこの間からお見せしている、結構長くてうんざりしてしまうようなプログラムなのですけれど、この何本かのプログラムは全部、現実に、「つくるCPU」の試作基板の上でちゃんと実行されているのですよ。
つまり、8080の命令が、本当に、そのまま実行されているのですよねぇ。
これって、ちょいと、すごいことだとは、思いませんか?

そうなんですねー。
模型だとか、モデルだとか、ただのオモチャなどではなくて、現実にちゃんと動作してくれるホンモノなのですよぉ。

じつは、かく言うこの私自身が、
「うわぁ、とうとう、ホントに、ホンマモンを作ってしもうたわぁ」
と、ちょいと、感動しているところなのです。
2009.6.30upload

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