復活!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 |