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

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第315回]


●I/Oレジスタへのアクセス方法(2)

前回の説明の中で、I/Oレジスタに00Hを書き込む場合に限っては、普通のOUT命令(コードD3XX)が使えるはず、と書きました。
念のために、テストプログラムをそのように変更して試してみました。
下は前回使用しましたテストプログラムの先頭部分を普通のOUT命令に書き換えたプログラムのリストです(先頭の変更した部分のみ示します)。

2013/2/10  21:7  e80time3.txt
END=802A
              ;;; music 09/10/9 10/10 10/12 10/15 
              ;;;
              ;;;MUSIC from MYCPU80 MUSIC
              ;10/6/4 6/5 6/15 for ND80Z3 CLK=6MHz
              ;7/20 9/24
              ;12/11/27 for E-80 clock?
              ;13/1/27
              ;2/6 time test
              ;2/10
              ;
              	ORG $8000
              ;
8000 AF       	XOR A
8001 D332     	OUT (32),A
8003 D336     	OUT (36),A
8005 310000   START:LD SP,$0000

実行してみましたところ、結果は変更前と全く変わらず、期待した通りになりました。



CPUクロックは20MHzです。
前回のプログラムではI/Oアクセスのウェイトはデフォルトの4クロックでしたが、今回は最少の1クロックウェイトになっています。
[第313回]の計算ではWRITEパルス幅が25ns不足するはずですが、それでもちゃんと動作してくれました。

●I/Oレジスタにアクセスするもうひとつの方法

前回はI/Oレジスタのアクセス方法としてはOUT(C),rを使うこともできるはず、ということも書きました。
その方法も念のために試してみました。

下はそのように変更したプログラムリストです(先頭の変更した部分のみ示します)。

2013/2/10  21:7  e80time4.txt
END=802F
              ;;; music 09/10/9 10/10 10/12 10/15 
              ;;;
              ;;;MUSIC from MYCPU80 MUSIC
              ;10/6/4 6/5 6/15 for ND80Z3 CLK=6MHz
              ;7/20 9/24
              ;12/11/27 for E-80 clock?
              ;13/1/27
              ;2/6 time test
              ;2/10
              ;
              	ORG $8000
              ;
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 310000   START:LD SP,$0000

このプログラムについても、実行結果は変更前と全く同じでした。



CPUクロックは20MHzです。
こちらもI/Oアクセスのウェイトは最少の1クロックウェイトになっています。
特に誤動作することもなく正しく動いてくれました。

●82C55の出力テスト

上で行なったテストでは、I/Oアクセス時のウェイトを最少の1クロックウェイトにしましたから、CPUクロックが20MHzでは、WRITEパルス幅が25ns不足します([第313回])。
それでも実行してみた結果では、特に誤動作することなく正しく実行できました。

計算上は誤動作しても当たり前のところなのですが、そのように誤動作することもなく動いてしまいますと、一体どのくらい誤動作せずに動いてくれるのか、ちょいとそのあたりを追求したくなってきます。
今までのテストはいずれも82C55に値を書き込むのはほんの一瞬で、その前後はタイマールーチンで時間かせぎをしています。
言ってみれば、82C55への書き込みはごくたまにしか行なわれないわけで、だから誤動作しなかった、とも考えられます。
もしも目一杯繰り返してアクセスしてみたら、そのうちポロリと誤動作してしまうのでは?

そのあたりを追求してみるとしましたら、前回でも使いました1msのパルス出力プログラムは不適当です。
目一杯アクセスして、どうなるかを試したいわけですから、出力の合間にタイマールーチンなどがあっては都合が悪いわけです。
ですから今回のテストプログラムでは間に何もはさまないで最短で出力のHとLを切り換えるように考えます。

そのようにするのは実際のところ実に簡単で、今まで82C55のPC1からHとLを交互に出力するたびにCALLしていたタイマールーチン(T1MS)を削除してしまえばよいのです。
それだけのことならわざわざ新しくソースプログラムを作成してアセンブラにかけたりしなくても、CMコマンドでちょいちょいと直してしまうほうが簡単です。

前回実行しましたテストプログラムをそのように直しました。

>/ld e80time2.bin,8000
loading E80TIME2.BIN ...0030(48)bytes loaded,from 8000 to 802F
>dm 8000,802f
8000  3E 3F ED 39 36 3E 30 ED-39 32 31 00 00 3E 88 D3  >?.96>0.921..>.モ
8010  FB 3E 03 D3 FB CD 22 80-3E 02 D3 FB CD 22 80 C3  .>.モ.ヘ".>.モ.ヘ".テ
8020  11 80 F5 3E 5F E5 E5 E1-E1 00 3D C2 25 80 F1 C9  ...>_.....=ツ%..ノ
>cm 8006
8006 30-00
8007 ED-
>cm 8015
8015 CD-3e
8016 22-02
8017 80-d3
8018 3E-fb
8019 02-c3
801A D3-11
801B FB-80
801C CD-

何をやってるのかよくわからないよ、という方のために。
こちらが変更前のプログラムです。
前回お見せしたプログラムです(必要な部分のみを再掲しました)。

              ;
                ORG $8000
              ;
8000 3E3F     LD A,3F; refresh off
8002 ED         DB ED;OUT0 (36),A
8003 39         DB 39;
8004 36         DB 36;
8005 3E30       LD A,30; memory wait off
8007 ED         DB ED;OUT0 (32),A
8008 39         DB 39;
8009 32         DB 32;
800A 310000   START:LD SP,$0000
800D 3E88       LD A,88;A=out,B=out,CH=in,CL=out
800F D3FB       OUT (FB),A
8011 3E03     LOOP:LD A,03         ;sp out=H (pc1=H)
8013 D3FB       OUT (FB),A
8015 CD2280     CALL T1MS
8018 3E02       LD A,02         ;sp out=L (pc1=L)
801A D3FB       OUT (FB),A
801C CD2280     CALL T1MS
801F C31180     JP LOOP

それを下のように変更しました。
変更したのはアドレス8006Hと8015H〜801BHです。

              ;
                ORG $8000
              ;
8000 3E3F     LD A,3F; refresh off
8002 ED         DB ED;OUT0 (36),A
8003 39         DB 39;
8004 36         DB 36;
8005 3E00       LD A,00; memory wait off
8007 ED         DB ED;OUT0 (32),A
8008 39         DB 39;
8009 32         DB 32;
800A 310000   START:LD SP,$0000
800D 3E88       LD A,88;A=out,B=out,CH=in,CL=out
800F D3FB       OUT (FB),A
8011 3E03     LOOP:LD A,03         ;sp out=H (pc1=H)
8013 D3FB       OUT (FB),A
8015 3E02       LD A,02         ;sp out=L (pc1=L)
8017 D3FB       OUT (FB),A
8019 C31180     JP LOOP
              ;

そのように変更したプログラムを実行しました。


上側(CH1)がWR信号で下側(CH2)が82C55のPC1からの出力信号です。
出力Lの期間は約1.3μsです。
8017HのOUT命令の直後に出力がLになって、8019HのJP命令(9クロック)、8011HのLD命令(6クロック)、8013HのOUT命令(10クロック)の実行後に出力がHになるまでがその期間ですから、その間の各命令のクロック数を計算すると、9+6+1025クロックになります。
CPUクロックは20MHzですから、1クロックは0.05μs(50ns)です。
0.05×251.25(μs)
計算通りです。
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
[2013.2.12訂正]
OUT命令のクロック数は11クロックでした。
したがって計算は0.05×26=1.3(μs)になります。
詳細については[第316回]を参照してください。
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

問題はWR信号の幅です。
これではちょっと分かりにくいので、スケールを倍にしてみました。


やはりWRパルス幅は0.12μs程度しかありませんね。
[第313回]で説明しました通り、CPUクロックが20MHzでは、82C55A−2で必要なWRパルス幅150nsにはかなり足りないことが実証されました。
しかし、このままかなり長い時間観測しましたが、特に誤動作しているようには見えませんでした。

もっともこのように超高速で82C55からH、Lを出力していますから、途中でたまにコケていても全く気がつかないだけかもしれません。

むむ。
そういうことになりますと。
もう少しテストの方法を工夫してみる必要があるかもしれません。

ワンボードマイコンでCP/Mを![第315回]
2013.2.11upload
2013.2.12一部訂正

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