16ビットマイコンボードの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使ってみるつもりで入手してそのまま置いてあった16ビットCPUのことを思い出しました。
AMD社のAM188です。
その名の通り、CPUコアは80188互換の16ビットCPUです。
そのAM188を使った16ビットマイコンボードの製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第7回]
●最初のJMP命令
今回は多くの読者様にとりましては全く意味不明、何を言っているのかわからんぞ、という記述に終始することになるかと思います。
私自身の備忘録を兼ねておりますので、曲げてご了承いただきますようお願いいたします。
前回の終わりのところで、AM188(8086も同じ)のリセット後のスタートアドレスはFFFF0です、と書いたあとで、「どうにも納得できないおかしなことに気が付きました」と書きました。
なにしろ80188(8086)を実際にさわるのはこれが初めてですので、まだしっかり理解できていないところが多々あります。
実は、先日からお見せしております16ビット版TK−80モニタプログラムの最初のスタート部分がおかしい、ということに気が付いたのです。
その最初の部分はこうでした。
[00003] ORG=F000 [00053] F000 EB0490 START0:JMP START1 <F006> [00054] F003 E92301 BRK:JMP BRENT <F129> [00055] ; [00056] F006 BAA0FF START1:MOV DX,FFA0;umcs [00057] F009 B83FE0 MOV AX,E03F;128k,noready [00058] F00C EF OUT DX,AX [00416] ORG=FFF0 [00417] FFF0 E90DF0 JMP START0 <F000> |
FFF0(物理アドレスのFFFF0)にF000へのJMP命令を書いています。
つい8ビットと同じ感覚でこのように書いてしまいました。
8086では、おそらくはこれは誤りで多分CPUが暴走することになるはずでした。
ところがAM188ではこのように書いても暴走しないで意図した通りの動作をしています。
それで余計に悩んでしまったのでした。
[2017.1.6追記]
上で「暴走しないで」と書いたのは誤りであることがわかりました([第8回]参照)。
[追記ここまで]
どういうことかといいますと。
ちょっとわかりにくいとは思いますが、図で説明します。
下の図はAM188がアクセスできる1MBのメモリマップです。
リセットによってCSにはFFFFがセットされます。
つまりコードセグメントのベースアドレスはFFFF0になります。
セグメントのサイズは64KBですから、リセットによってコードセグメントは物理アドレスの0FFFF0〜10FFEFの範囲になるはずです。
ここからがややこしい話になります。
AM188がアクセスできる物理メモリの上限はFFFFFです。
するとリセット後に実際にアクセスできる実メモリアドレスはFFFF0〜FFFFFのわずか16バイトしかありません。
そういう条件のもとで、問題のプログラムリストのように、F000へのJMP命令を書いた場合、CPUはどこに飛ぶのでしょうか。
8086のJMP命令は相対ジャンプ命令ですから、コードセグメントの中で、つまり論理的な64KBのメモリ空間の中で指定された「相対的な」アドレスにジャンプします。
そこはFFFF0を0000とした場合のF000番地ですから、FFFF0+F000=10EFF0のはずです。
しかしそのアドレスはAM188では存在しないアドレスです。
8086の場合、内部レジスタは20ビットですから、そのアドレスは桁あふれを起こして、その結果として0EFF0にジャンプするのではないか、ということが推測されます。
実際に8086で試してみれば確認できるはずなのですが、手元に8086はありませんし、今のところそこまでする意味はありませんから、それはあくまで推測です。
しかしおそらくそうだろうと考える根拠はあります。
ネツト上で「8086 A20」で検索すると、上記の考えを裏付ける説明がみつかります。
さて、するとなぜAM188ではそのようにならず(つまり0EFF0にジャンプしないで)、コードセグメント外のFF000にジャンプできてしまうのか?という大きな疑問が出てきます。
これにはどうやらAM188のUCS(Upper memory Chip Select)が関係しているらしい、と見当をつけたのですが、AM188のDatasheetを何回も繰り返し読んでもどこにもそのようなことは書いてありません。
UCSは80188のメモリ制御端子で、普通はCPUの外でメモリアドレスからメモリのCS信号を作るところを、内部の特殊レジスタ(UMCS)に値を設定することで、指定した範囲のメモリのCS信号を出力します。
UCSの上限アドレスはFFFFF固定で、下限アドレスはリセット後はF0000になります。
よくはわかりませんが、AM188ではそうなります、ということにしてもよいのですけれど、どうにも気持ちがすっきりしません。
それで納得できないまま、何時間もかけてずっとネットで検索を続けておりましたら、やっと、それらしい記述をみつけました。
ファイル名は「AMD_80186_(1985).PDF」となっていますが、内容からするとどうもIntelの80186ファミリーのデータシートのコピーのようです。
表紙がないので正確なところはわかりません。
[出典]Intel 80186Datasheet?(赤線は筆者)
赤線で囲ったところに問題の答えが書かれているように思います。
ちょっとわかりにくい文章ですが、意訳すると次のようになると思います。
「(CPU内部で算出した)20ビットのアドレスの上位16ビットがUMCSの下位6ビットを0にした値と同じかそれよりも大きいときは、UCSがアクティブになる」
リセット後はUMCSの値(UMCSレジスタの設定値ではなくて上の表に示された値のこと)はF038Hになります。
その下位6ビットを0にした値はF0000Hです。
つまり上の説明を今回の問題にあてはめて解くと、リセット後はCS(コードセグメントレジスタ)の設定値に関係なく、F0000〜FFFFFの範囲のアドレスを指定すると、UCS端子がアクティブになって、その範囲のメモリにアクセスできる、ことになります。
これでやっとすっきりしました。
そういうことでしたら、プログラムリストのままでもよいわけですけれど。
あ。
実際にはCSレジスタには、F000にジャンプしたあと、その少し後ろのところで、F000を設定しています。
下のリストの[00080][00081]の行です。
[00052] ; [00053] F000 EB0490 START0:JMP START1 <F006> [00054] F003 E92301 BRK:JMP BRENT <F129> [00055] ; [00056] F006 BAA0FF START1:MOV DX,FFA0;umcs [00057] F009 B83FE0 MOV AX,E03F;128k,noready [00058] F00C EF OUT DX,AX [00059] F00D BAA2FF MOV DX,FFA2;lmcs [00060] F010 B83F1F MOV AX,1F3F [00061] F013 EF OUT DX,AX [00062] F014 BA70FF MOV DX,FF70;piomode0 [00063] F017 B80100 MOV AX,0001 [00064] F01A EF OUT DX,AX [00065] F01B BA72FF MOV DX,FF72;pdir0 [00066] F01E B80EFC MOV AX,FC0E [00067] F021 EF OUT DX,AX [00068] F022 BA78FF MOV DX,FF78;pdir1 [00069] F025 B8FEFF MOV AX,FFFE;pacs active [00070] F028 EF OUT DX,AX [00071] F029 BAA8FF MOV DX,FFA8;mpcs [00072] F02C B8B880 MOV AX,80B8 [00073] F02F EF OUT DX,AX [00074] F030 BAA4FF MOV DX,FFA4;pacs [00075] F033 B87608 MOV AX,0876;i/o base address=8000 [00076] F036 EF OUT DX,AX [00077] F037 BA8380 MOV DX,8083;**** 82c55 [00078] F03A B080 MOV AL,80;**** all port out [00079] F03C EE OUT DX,AL;**** [00080] F03D B800F0 MOV AX,F000 [00081] F040 8EC8 MOV CS,AX [00082] ; MOV AX,CS; [00083] ; MOV DX,8080; [00084] ; OUT DX,AX; [00085] ; [00086] ;monitor start [00087] ; |
でも、これでは余りに初心者的でみっともないプログラムですので、少しは、らしいプログラムに直すことにいたします。
本日は時間がなくなってしまいましたので、それについては次回に書くことにいたします。
16ビットマイコンボードの製作[第7回]
2017.1.4upload
2017.1.6追記
前へ
次へ
ホームページトップへ戻る