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

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

[第314回]


●Z8S180のI/Oレジスタ

Z8S180は内蔵しているタイマーやシリアルポートなどの動作モードの設定や、その他のいろいろなコントロールのために特殊なI/Oレジスタを内蔵しています。
I/Oレジスタはリセット後は、I/Oアドレスの0000H〜003FHに置かれますが、0040H〜007FH、0080H〜00BFH、00C0H〜00FFHに置くこともできます。

Z80のI/Oアドレスは00H〜FFHの256バイトでしたが、Z8S180ではI/Oアドレスもメモリアドレスと同じように0000H〜FFFFHの64KBに拡張されています。
したがってZ80では問題にならなかった、I/Oアクセス時のアドレス上位A8〜A15にも注意を払う必要が出てきます。

といいましてもCPUの外部に置く82C55などに対するアクセスについては、従来どおりアドレス下位8ビットのA0〜A7をデコードしている分には、Z80の場合とまったく同じように扱うことができますから、そのこと(I/Oアドレスが64KBに拡張されていること)を意識する必要は全くありません。

しかしZ8S180に内蔵されているI/Oレジスタは内部で上位8ビットのA8〜A15までを含めて完全デコードされていますから、Z80と同じI/Oアクセス方法ではアクセスできない場合がでてきます。
その具体的なアクセス方法については、後ほど説明いたします。

それでは、Z8S180に内蔵されているI/Oレジスタについての説明に入りますが、I/Oレジスタの全てについて説明をするのはここでの目的ではありません。
メモリアクセスやI/Oアクセス時に挿入されるウェイトクロックをコントロールすることが目的です。
ですのでここでは、そのウェイトクロックの挿入をコントロールしているI/Oレジスタについて説明いたします。

●DMA/WAIT CONTROL REGISTER

I/Oアドレス0032Hにそのレジスタがあります。


[出典]Zilog社 Z8S180 Product Specification

ビット7、ビット6の2ビットで、メモリアクセス時のウェイトクロックの挿入数を指定します。
00のとき0個、01のとき1個、10のとき2個、11のときは3個のウェイトクロックが挿入されます。
リセット後は11がセットされますから、3個のウェイトクロックが挿入されます。

ビット5、 ビット4の2ビットで、I/Oアクセス時のウェイトクロックの挿入数を指定します。
00のとき1個、01のとき2個、10のとき3個、11のときは4個のウェイトクロックが挿入されます。
リセット後は11がセットされますから、4個のウェイトクロックが挿入されます。

ビット3〜0はDMAコントロールです。
リセット後は各ビットとも0になります。

●REFRESH CONTROL REGISTER

E−80(仮称)ミニコンではDRAMは扱いませんからリフレッシュは不要です。
リフレッシュをコントロールしているI/OレジスタはI/Oアドレス0036Hにあります。



ビット7が1のときリフレッシュサイクルが実行されます。
ビット7が0のときリフレッシュは行なわれません。
リセット後はビット7=1になります。

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

以上説明しましたことから、メモリアクセス時のウェイトを0にし、I/Oアクセス時のウェイトは最小の1クロックにするには、I/Oアドレス0032Hに00Hを書き込みます。
またリフレッシュを禁止するにはI/Oアドレス0036Hに00Hを書き込みます。

それでは、I/Oアドレス00XXHのI/Oレジスタに値を書き込むにはどうしたらよいかについて説明をいたします。
I/Oアドレスに何かを書き込む(出力する)ということになりますと、まずは普通のOUT命令 OUT (n),A (マシン語コードD3XX)を使うことが考えられます。
この命令は8080のときからある命令ですが、Z80ではコードD3XXのOUT命令は、上位アドレスA8〜A15にAレジスタの値が出力されます。

あれ?
今気がついたのですが、今回はI/Oアドレス0032H、0036Hにともに00Hを書き込めはよいのですから、それならちょうど普通のOUT命令を使って、
XOR A
OUT (32),A
OUT (36),A
を実行すればよい、ですねえ。
むむ。
あとで試してみましょう。

これはたまたま00Hを書き込むときだけ使えるテクニックです。
00H以外を書き込むときには、この命令は使えません。

次にZ80で追加された命令OUT(C),rを使うことを考えてみます。

[出典]Zilog社 Z80185 User’s Manual

OUT(C),rは、アドレス下位A0〜A7にCレジスタの値が出力され、上位A8〜A15にBレジスタの値が出力されます。
ですから、この命令を使ってI/Oアドレス0032Hと0036Hに00Hを書き込むには下のようにプログラムします。
XOR A
LD BC,$0032
OUT (C),A
LD C,36
OUT (C),A

●OUT0 (n),r

Z8S180ではZ80にはなかったいくつかの命令が追加されています。
そのうちの OUT0 (n),r という命令を使うとI/Oアドレスの00XXHに値を書き込むことができます。



この命令は、I/Oアドレスの上位8ビットA8〜A15に常に00Hを出力します。
マシン語コードはEDで始まる3バイトです。
Aレジスタの値を出力する場合には、第2バイトのコードは39Hになります。
第3バイトはI/Oアドレスの下位8ビットの値です。

この命令はND80ZV(ND80Z3.5)に付属のZ80アセンブラZASM.COMにはありません。
ですからDB命令を使って直接16進数でコーディングします。

この命令を使ってI/Oアドレス0032Hと0036Hに00Hを書き込むには下のようにプログラムします。
XOR A
DB ED
DB 39
DB 32
DB ED
DB 39
DB 36

●テストプログラム

[第312回]で使った1msecのパルス出力プログラムの先頭に、リフレッシュ禁止とウェイト無しを設定した部分を付け加えました。

2013/2/8  10:10  e80time2.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
              ;
              	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
              ;
8022 F5       T1MS:PUSH AF		;CK=11....11+7+10+10+10=48/6(8microsec)
8023 3E5F     	LD A,5F		;=99  CK=7
8025 E5       T1MS2:PUSH HL;DUMMY CLK=11-----------------
8026 E5       	PUSH HL;DUMMY CLK=11               |
8027 E1       	POP HL;DUMMY CLK=10                |CK=60/6(10microsec)
8028 E1       	POP HL;DUMMY CLK=10                |
8029 00       	NOP ;CLK=4                         |
802A 3D       	DEC A		;CK=4        |10x99=990microsec
802B C22580   	JP NZ,T1MS2	;CK=10---
802E F1       	POP AF		;CK=10
802F C9       	RET		;CK=10 + CALL CK=10
              ;END
LOOP         =8011  START        =800A  T1MS         =8022  
T1MS2        =8025  

このプログラムを作った時点ではI/Oレジスタについて詳しく調べていませんでしたので、リフレッシュ禁止のために3FHをI/Oアドレスの0036Hに書き込んでいます。
ここは上に書きましたように、おそらく00Hを書き込むということでもよいはずです。
またこのテストプログラムではI/Oアクセス時のウェイトは全体の動作にほとんど影響しませんから、I/Oアクセス時のウェイトについてはデフォルトと同じ4回のままにしています(ビット5、ビット4=11)。

●テストプログラムの実行結果です

上のプログラムをCPUクロック10MHzで実行してみました。


おお。
CPUクロック6MHzのND80ZV(ND80Z3.5)で1msだったところがその半分の約0.5msになりました。
これは速い!

時間軸のスケールを0.1msにしてみました。


0.54msです。
6MHzのZ80で1msに設計したところが0.54msになったのですから、そこからZ80に換算したクロック周波数を計算してみますと
6/0.54≒11(MHz)
になります。
メモリアクセスをノンウェイトにすると、CPUクロック10MHz時にはZ80換算で11MHzのパフォーマンスが得られたことになります。
Z8S180では、Z80で1マシンサイクルが4クロックの多くの命令を1クロック短縮して3クロックにしていますから、そのことがこのパフォーマンスになったと思われます。
むむ。
これなら、納得です。

続いて同じプログラムをCPUクロックを20MHzにして実行してみました。



ちょうど1/2の0.27msになりました。
こちらもZ80に換算したクロック周波数を計算してみます。

6/0.27≒22(MHz)

おお。
Z80に換算して22MHzのパフォーマンスが得られました。
またまた、納得です。

今回はとりあえずメモリアクセス時のみノンウェイトにしてテストを行ないました。
その結果は非常に満足できるものでした。

次回はCPUクロック20MHz時の82C55アクセスについて試してみることにいたします。

ワンボードマイコンでCP/Mを![第314回]
2013.2.10upload

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