復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります!
[第317回]
●82C55A−2耐久テストプログラム
前回までのところで82C55A−2にCPUクロック20MHzでアクセスするテストを行なってきました。
しかしテストの方法がちょっと中途半端でしたので、途中で誤動作していたとしても、そのことがはっきりわからないという疑いがありました。
また今までは82C55A−2の出力テストのみで、入力テストは行なっていませんでした。
前回は82C55A−2に対して繰り返し入力を行なっているところの信号波形の写真をお見せしましたが、それはCSとRDのタイミングを確認するだけの目的でしたので、正しく82C55A−2からデータを読んでいるのかどうかについては何もわかりません。
そこでどの程度正しく動作するものなのかどうかということを確認してみることにしました。
この目的のためには、ある程度長時間82C55A−2に対して出力、入力を繰り返して、かつその値が正しく出力、入力されていることが確認できる必要があります。
下はそのために作ったマシン語のテストプログラムです。
2013/2/11 8:52 e80iorwt.txt END=8070 ;;; E-80 82c55 read/write test ;13/2/11 ; ORG $8000 ; PA=$F440 PB=$F442 ; 8000 AF XOR A 8001 013200 LD BC,$0032 8004 ED79 OUT (C),A 8006 0E36 LD C,36 8008 ED79 OUT (C),A ; 800A 3E80 START:LD A,80 800C D3E3 OUT (E3),A 800E D3E7 OUT (E7),A 8010 D3EB OUT (EB),A 8012 D3EF OUT (EF),A 8014 50 LD D,B 8015 58 LD E,B 8016 60 LD H,B 8017 68 LD L,B 8018 7B LOOP:LD A,E 8019 D3E0 OUT (E0),A 801B D3E1 OUT (E1),A 801D D3E2 OUT (E2),A 801F D3E4 OUT (E4),A 8021 D3E5 OUT (E5),A 8023 D3E6 OUT (E6),A 8025 D3E8 OUT (E8),A 8027 D3E9 OUT (E9),A 8029 D3EA OUT (EA),A ;check 802B DBE0 IN A,(E0) 802D BB CP E 802E 2039 JR NZ,INERR 8030 DBE1 IN A,(E1) 8032 BB CP E 8033 2034 JR NZ,INERR 8035 DBE2 IN A,(E2) 8037 BB CP E 8038 202F JR NZ,INERR 803A DBE4 IN A,(E4) 803C BB CP E 803D 202A JR NZ,INERR 803F DBE5 IN A,(E5) 8041 BB CP E 8042 2025 JR NZ,INERR 8044 DBE6 IN A,(E6) 8046 BB CP E 8047 2020 JR NZ,INERR 8049 DBE8 IN A,(E8) 804B BB CP E 804C 201B JR NZ,INERR 804E DBE9 IN A,(E9) 8050 BB CP E 8051 2016 JR NZ,INERR 8053 DBEA IN A,(EA) 8055 BB CP E 8056 2011 JR NZ,INERR ; 8058 7B LD A,E 8059 D3EC OUT (EC),A 805B 7A LD A,D 805C D3ED OUT (ED),A 805E 7D LD A,L 805F D3EE OUT (EE),A 8061 13 INC DE 8062 7B LD A,E 8063 B2 OR D 8064 20B2 JR NZ,LOOP 8066 2C INC L 8067 20AF JR NZ,LOOP ; 8069 ED5340F4 INERR: LD (PA),DE 806D 2242F4 LD (PB),HL 8070 C9 RET ; ;END INERR =8069 LOOP =8018 PA =F440 PB =F442 START =800A |
プログラムの最後を見ていただきますと分かりますように、これはサブルーチンです。
テストそのものはマシン語プログラムだけでもできますが、途中の時間経過とか繰り返し回数の表示とかというものも行ないたいということになりますと、その部分はBASICが圧倒的に便利です。
ですのでメインルーチンはBASICで書くことにして、マシン語プログラムはそのサブルーチンとしてBASICプログラムからCALLするようにしました。
プログラムの簡単な説明です。
8000H〜8009Hではリフレッシュの禁止とメモリアクセスのウェイトクロック数を0、I/Oアクセスのウェイトクロック数を1にしています([第315回]参照)。
ここに置くとBASICからCALLされるたびに毎回設定をすることになりますが、そのようにしても問題はありませんから、設定部分を分けて別の処理プログラムにするわずらわしさを避けるため、このようにしました。
800AH〜8013Hでは82C55A−2の全ポートの向きを出力に設定しています。
この部分についても上記と同じで毎回設定を行なう必要はありませんが、プログラム処理を簡略にするために、このようにしました。
E−80(仮称)ミニコンには82C55A−2が5個搭載されています。
そのうちアドレスF8H〜FBHの1個はシステムで使います。
残りの4個(アドレスE0H〜E3H、E4H〜E7H、E8H〜EBH、ECH〜EFH)はユーザー用に開放されています。
8014H〜8017Hではカウンタ用のレジスタD,E,H,Lをクリアします。
8018H〜802AHで、Eレジスタの値を3つの82C55(E0H〜E3H、E4H〜E7H、E8H〜EBH)のAポート〜Cポートに順に出力します。
次に802BH〜8057Hで、今出力をし終わった各ポートから値を読み込みます。
82C55では出力に設定されているポートに対して入力を行なうと、出力ポートにラッチされている値がそのまま読み込まれます。
当然このときはIN命令を実行しますから、ポートが入力に設定されているときと同じ動作になります。
ですので出力に設定されていても、そのままで入力動作のテストも行なえるのです。
読み込んだ値をEレジスタと比較します。
不一致ならエラー処理(INERR、8069H)にジャンプします。
8069Hのエラー処理では、DEレジスタの値をF440H、F441Hに、HLレジスタの値をF442H、F443Hに書き込んでメインルーチン(BASICプログラム)にリターンします。
F440H、F441HはBASICの整数変数A%の、F442H、F443Hは整数変数B%のアドレスです。
このようにすることによってBASICプログラムで、カウンタの値を知ることができます。
全ポートの値を比較して全て一致していたときは、次の8058Hの処理に移ります。
8058HではアドレスECH〜EFHの82C55A−2のAポート〜Cポートに、レジスタE、D、Lの値を出力します。
この82C55A−2の出力にLEDを接続して、進行状況を確認することができるようにするためです。
そのあとDEレジスタの値を+1して、もしその値が一巡して0000Hになったのでなければ、LOOP(8018H)に戻って処理を繰り返します。
DEレジスタが0000H〜FFFFHまで、65536回同じ処理が繰り返されます。
その間82C55A−2の各ポートには00H〜FFHの出力が256回繰り返し行なわれます。
DEレジスタが一巡して0000HになったらLレジスタを+1して、その値が00HでなければLOOP(8018H)に戻って処理を繰り返します。
ここではさらに256回繰り返しが行なわれますから、結局8018H〜8065Hの処理が65536×256=16777216回繰り返し行なわれることになります。
繰り返しが完了したら、エラーのときと同様にDEレジスタとHLレジスタの値をA%、B%に格納してBASICにリターンします。
正常に終了したときはA%もB%もともに0になりますから(HL=0000H、DE=0000H)、それを調べることでエラーが発生したのか、それとも正常に終了したのかを知ることができます。
処理の第1回目でエラーが発生したときは、HL=DE=0000Hですから正常に終了したときと区別できないじゃないか、と思われるかも知れませんが、最初のところに書きましたようにBASICプログラムでは時間経過も表示しておりまして、実はこのマシン語プログラムはCPUクロック20MHzでも正常に終了してリターンするまでに5分近くかかります。
ですから第1回目でエラーになってリターンしたのか、正常に処理を終了してリターンしたのかは時間の経過を見れば一目瞭然なのです。
さてそれではいよいよBASICのメインプログラムのご紹介と、実行を開始したときの様子をお見せすることにいたします。
E−80(仮称)ミニコンをWindowsパソコンとUSBで接続して、ZB3BASICを起動しています。
最初に/LDコマンドでマシン語プログラムを8000Hからロードしました。
次にBASICプログラムの作成をします。
最初のNEW 8100は、マシン語プログラムをBASICのTEXTエリアの先頭部分、8000Hに置きましたから、BASICプログラムがその領域を破壊しないようにするために実行しています。
NEWコマンドはBASICプログラムを書き始めるアドレスを指定するコマンドで、NEW 8100とすることで、8000H〜80FFHは、BASICが使わない領域としてリザーブされます。
BASICプログラムはとても簡単ですから、あえて説明をする必要もありませんでしょう。
RUN[Enter]で実行を開始しました。
開始時刻は16:40:07です。
その下の16:44:59は1回目の処理が終ってリターンしてきたことを示しています。
4分52秒かかっています。
のちほどこの時間とマシン語プログラムの命令クロック数の計算から、CPUクロックが本当に20MHzで動いていることを確認いたします。
こちらはテスト中の様子です。
82C55A−2の出力にLEDを接続してモニタしています。
なにしろマシン語サブルーチンからリターンしてくるまでに5分近くもかかってしまうものですから、万一途中で何かのトラブルが発生してハングアップしたりしたときでも、すぐに分かるようにしておきたい、という考えからこのようにいたしました。
かなり時間が経過しました。
実行を開始してから6時間近くが経過しています。
途中で1回でもエラーが発生すれば、そこで実行は中止されますから、これだけの長い時間エラーなしで82C55A−2へのREAD、WRITEを繰り返していることになります。
このまま一晩続けておくことにいたしました。
いえ。
私は寝てしまいましたよ。
あとはパソコンとE−80(仮称)ミニコンだけが闇の中でひたすら働いているだけです。
とうとう翌朝になってしまいました。
なんと16時間が経過して、エラー無しです。
すばらしいじゃじゃありませんか!
この調子だとまだまだ続けていけそうですが、そうすると他の作業ができません。
ひとまずここで実行を終了いたしました。
参考までに。
下はこの間の実行を記録したログファイルです。
logfile nd80zlog\02111636.txt open ND80ZVに接続しました 0001 0000 - z 1000 00C3 - *** nd80z3 basic **** >/ld e80iorwt.bin,8000 loading E80IORWT.BIN ...0071(113)bytes loaded,from 8000 to 8070 >new 8100 >10a=0 >20usr($8000) >15p."start",time$ >30p.time$,b%,a% >30p.time$,a >40a=a+1 >50if a%+b%=0 g.20 >60p."error",b%,a% >list 10 A=0 15 PRINT "start",TIME$ 20 USR($8000) 30 PRINT TIME$,A 40 A=A+1 50 IF A%+B%=0 GOTO 20 60 PRINT "error",B%,A% >run start 16:40:07 16:44:59 0 16:49:52 1 16:54:44 2 16:59:37 3 17:04:29 4 17:09:22 5 17:14:14 6 17:19:07 7 17:23:59 8 17:28:52 9 17:33:44 10 17:38:37 11 17:43:29 12 17:48:22 13 17:53:14 14 17:58:07 15 18:02:59 16 18:07:52 17 18:12:44 18 18:17:37 19 18:22:29 20 18:27:22 21 18:32:14 22 18:37:07 23 18:41:59 24 18:46:52 25 18:51:44 26 18:56:37 27 19:01:29 28 19:06:22 29 19:11:14 30 19:16:07 31 19:20:59 32 19:25:52 33 19:30:44 34 19:35:37 35 19:40:29 36 19:45:22 37 19:50:14 38 19:55:07 39 19:59:59 40 20:04:52 41 20:09:44 42 20:14:37 43 20:19:29 44 20:24:22 45 20:29:14 46 20:34:07 47 20:38:59 48 20:43:52 49 20:48:44 50 20:53:37 51 20:58:29 52 21:03:22 53 21:08:14 54 21:13:07 55 21:17:59 56 21:22:52 57 21:27:44 58 21:32:37 59 21:37:29 60 21:42:22 61 21:47:14 62 21:52:07 63 21:56:59 64 22:01:52 65 22:06:44 66 22:11:37 67 22:16:29 68 22:21:22 69 22:26:14 70 22:31:07 71 22:35:59 72 22:40:52 73 22:45:44 74 22:50:37 75 22:55:29 76 23:00:22 77 23:05:14 78 23:10:07 79 23:14:59 80 23:19:52 81 23:24:44 82 23:29:37 83 23:34:29 84 23:39:22 85 23:44:14 86 23:49:07 87 23:53:59 88 23:58:52 89 00:03:44 90 00:08:37 91 00:13:29 92 00:18:22 93 00:23:14 94 00:28:07 95 00:32:59 96 00:37:52 97 00:42:44 98 00:47:37 99 00:52:29 100 00:57:22 101 01:02:14 102 01:07:07 103 01:11:59 104 01:16:52 105 01:21:44 106 01:26:37 107 01:31:29 108 01:36:22 109 01:41:14 110 01:46:07 111 01:50:59 112 01:55:52 113 02:00:44 114 02:05:37 115 02:10:29 116 02:15:22 117 02:20:14 118 02:25:07 119 02:29:59 120 02:34:52 121 02:39:44 122 02:44:37 123 02:49:30 124 02:54:22 125 02:59:15 126 03:04:07 127 03:09:00 128 03:13:52 129 03:18:45 130 03:23:37 131 03:28:30 132 03:33:22 133 03:38:15 134 03:43:07 135 03:48:00 136 03:52:52 137 03:57:45 138 04:02:37 139 04:07:30 140 04:12:22 141 04:17:15 142 04:22:07 143 04:27:00 144 04:31:52 145 04:36:45 146 04:41:37 147 04:46:30 148 04:51:22 149 04:56:15 150 05:01:07 151 05:06:00 152 05:10:52 153 05:15:45 154 05:20:37 155 05:25:30 156 05:30:23 157 05:35:15 158 05:40:08 159 05:45:00 160 05:49:53 161 05:54:45 162 05:59:38 163 06:04:30 164 06:09:23 165 06:14:15 166 06:19:08 167 06:24:00 168 06:28:53 169 06:33:45 170 06:38:38 171 06:43:30 172 06:48:23 173 06:53:15 174 06:58:08 175 07:03:00 176 07:07:53 177 07:12:45 178 07:17:38 179 07:22:30 180 07:27:23 181 07:32:15 182 07:37:08 183 07:42:01 184 07:46:53 185 07:51:46 186 07:56:38 187 08:01:31 188 08:06:23 189 08:11:16 190 08:16:08 191 08:21:01 192 08:25:53 193 08:30:46 194 08:35:38 195 08:40:31 196 08:45:23 197 break in 30 > > > >list 10 A=0 15 PRINT "start",TIME$ 20 USR($8000) 30 PRINT TIME$,A 40 A=A+1 50 IF A%+B%=0 GOTO 20 60 PRINT "error",B%,A% >0000 00C3 - リモート接続を終了しました logfile closed at Tue Feb 12 08:51:28 2013 |