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
前へ
次へ
ホームページトップへ戻る