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


16ビットマイコンボードの製作

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使ってみるつもりで入手してそのまま置いてあった16ビットCPUのことを思い出しました。
AMD社のAM188です。
その名の通り、CPUコアは80188互換の16ビットCPUです。
そのAM188を使った16ビットマイコンボードの製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第17回]


●OUT命令

16ビットマイコンボードについてはおよそ1ヶ月振りの更新です。
このところ「マイコン独立大作戦」を中心にして書いてきております。
実は昨日書きました8086アセンブラを使ったVGA表示画面のテストプログラム(「マイコン独立大作戦」[総合第16回])の続きを書こうとして、OUT命令でひっかかってしまいました。
以前からちょっとまずいかなあ、とは思っていたのですが、ここにきてやっぱりこのまま進むわけにはいかんなあ、と思いましたので、今回は「16ビットマイコンボードの製作」に戻って、出直すことにいたしました。

AM188にはI/Oを制御するための端子が6本あります。
PCS0〜PCS3、PCS5、PCS6です。
各端子にはあらかじめアクティブにできるI/Oアドレス範囲を指定します。
その範囲のアドレスを指定したときだけ出力がアクティブになります。
AM188マイコンボードではそのうちのPCS0を使います。
とりあえず作成したTK−80風モニタプログラムの初期設定部分で、PCS0には8000〜80FFの範囲を割り当てました。
AM188ではI/Oアドレスは16ビットなので0000〜FFFFの範囲をアクセスすることができます。
そのうちの8000〜80FFです。
なぜ8000〜なのかといいますと、ちょうど真ん中のアドレスなので、というようないい加減な理由で決めたものです([第16回])。

この時点では「仮に」のつもりでしたし、後でよく考えればいい、と軽く考えていました。
しかし後で、なんて言っていないでこの時点でよく考えるべきでありました。

今までの8086のOUT命令(IN命令も)については、アドレスはDXレジスタのみを使って、
MOV AL,FF
MOV DX,80D0
OUT DX,AL
のように書きます。
と説明してきました。

実は8086のOUT命令はこのほかに8080の命令と同じように、8ビットのIOアドレスを指定することができます。
OUT D0,AL
OUT 83,AX
という使い方です。

実際にVGA画面表示プログラムを書いて、8080やZ80のプログラムと比較してみますと、DXを使うよりも、8ビットCPUと同じ、こちらのOUT命令のほうがはるかに使い易いのですよね。
ところが現状では、8ビットアドレスを指定するOUT命令は使えません。
余りよく考えないでPCS0のベースアドレスとして8000なんて値を割り当ててしまったからです。

OUT xx,AL
という命令を使う場合xxには00〜FFが入るのですが、そのときの上位8ビットはどうなるのか?という問題です。
じつは
OUT xx,AL
OUT xx,AX
IN AL,xx
IN AX,xx
の4つの命令はCPUがその命令を実行するときに上位8ビットのアドレスとして00を補完するのです。
つまり
OUT D0,ALは
MOV DX,00D0
OUT DX,AL
と同じ動作になります。

ところが現在はモニタプログラムの初期設定で、PCS0に8000〜80FFを割り当てているために
MOV DX,80D0
OUT DX,AL
は実行できても
OUT D0,AL
は実行できません。
なぜならOUT D0,ALは00D0に対するOUT命令になってしまうからです(この型のOUT命令は0000〜00FF以外のI/Oアドレスはアクセスできません)。

ということになりますと、ここはやっぱりPCS0に0000〜00FFを割り当てるべきでありましょう。
覚悟を決めまして、モニタプログラムを書き直しました。
初期設定部分だけではなくて、キーアクセスなどの部分でDXを使ってI/Oアドレスとして80xxを指定しているところを全部書き直しました。

下は変更前のモニタプログラムのI/Oアドレスの設定部分です。

[00066] F01C  BAA4FF            MOV DX,FFA4;pacs
[00067] F01F  B87608            MOV AX,0876;i/o base address=8000
[00068] F022  EF                OUT DX,AX
[00069] F023  BA8380            MOV DX,8083;**** 82c55
[00070] F026  B080              MOV AL,80;**** all port out
[00071] F028  EE                OUT DX,AL;****
[00072] F029  8CC8              MOV AX,CS;*****
[00073] F02B  BA8080            MOV DX,8080;*****
[00074] F02E  EF                OUT DX,AX;*****

こちらは変更後です。

[00066] F01C  BAA4FF            MOV DX,FFA4;pacs
[00067] F01F  B87600            MOV AX,0076;i/o base address=0000 17.2.24
[00068] F022  EF                OUT DX,AX
[00069] F023  B080              MOV AL,80;all port out
[00070] F025  E683              OUT 83,AL;82C55
[00071] F027  8CC8              MOV AX,CS;***** test
[00072] F029  E780              OUT 80,AX;*****

I/Oアドレスを設定してから、82C55の全ポートを出力に設定し、テストとしてCS(Code Segment register)の値をAポートとBポートに出力しています。
ボード上の82C55はND80Z3.5と同様、I/Oアドレス80〜83に割り付けています。
こうやって両者を比較してみますとやっぱり8ビットアドレスを直接指定するほうが簡単ですね。
OUT、INの度にDXレジスタが占領されてしまうというのもデメリットです。
もちろんこのように変更したあとでもDXレジスタを使って
MOV DX,0083
OUT DX,AL
としても全く支障はありません。

16ビットマイコンボードの製作[第17回]
2017.2.24upload

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