• ベストアンサー

マイコンのバンク切り替え

最近、マイコンのプログラミングをはじめたのですが、相手方の技術者が主張するバンク切り替え方法が腑に落ちないので、この投稿で質問します。 問題はバンク切替えの方法で、CPUは日立64180です。 メモリーの構成は次のようになっています。   ┌──┐   │  │主プログラム   │  │のメモリー   │  │   └──┘ ┌──┐┌──┐ │BANK││BANK│切替プログラム │ 0 ││ 1 │のメモリー │  ││  │ └──┘└──┘ この構成にを前にして、相手側技術者の主張は、次のようなものでした。   BANK-0   BANK-1 ┌────┐┌────┐ │ │  ││    │ │ │  ││    │切替プログラム │切替命令││    │ のメモリー │ └──┼┼─┐  │ │    ││ ↓  │ │    ││    │ └────┘└────┘ BANK-0のプログラムでBANK-1に切り替える命令を発行すると、直ちにBANK-1に切替わり、BANK-1の同じアドレスの次アドレスからプログラムが続行するというのです。 これだと、BANK-0,BANK-1の先頭番地からプログラムを実行させる方法が思いつきません。 私の考えは、主プログラム側で予め必要なバンクに切替えておき、切替えたバンクの先頭番地に制御を移せば済むと思うのですが、どうなのでしょう? 日立64180アーキテクチャに詳しくないので、反証すらできません。経験された方に確実な回答をお願いする次第です。

質問者が選んだベストアンサー

  • ベストアンサー
  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.3

バンク切り替えの方法としてHD64180のMMUを使用しているものと仮定すると、HD64180R/Zのデータシートを読んだところでは、仕様上の問題はないようです。 データシートにはこうあります。 "7.8 MMU Register Access Timing" "When data is written into CBAR, CBR, or BBR, the value will be effective from the cycle immediately following the I/O write cycle which updates these registers." "Observe that the next cycle following MMU register programming will normally be an opcode fetch from the newly translated address." ですので、「私が調べたデータシート」に記載の仕様の上では、相手側技術者の主張は正しいようです。 #注意:たまたま私が調べたデータシートでは上記のとおりでしたが、HD64180にはバリエーションチップがたくさんあり、そのすべてがMMUに関して同一仕様とは限りません。 仕様の上で制限されていないからといって、それを行うべきかどうかはまた別問題です。たまたまそのCPUが「私がデータシートを調べたのと同じCPU」であれば大丈夫ですが、プリフェッチを行うCPUだった場合にはそのようなプログラムの構造ですとちゃんと動きません。 そのような、仕様の細かいところまで確認しなければ動作に確証がもてないようなプログラムを作ることは、好まくないプログラミング手法と呼ばざるを得ません。どうしてもそれ以外の方法がないのであれば仕方がないですが(そういう場合も稀にあります)、他の「安全な方法」があるのにわざわざ危険を冒すのは〇〇(ここに書くと発言を削除されてしまうような不穏当な文言だと思ってください)のすることだと、個人的には思います。

koma1000nin
質問者

お礼

回答ありがとうございます。 MMUはHD64180Z/HD64180R1ですが、全部を読んでいる時間がないのです。 "…an opcode fetch from the newly translated address." の部分で納得できました。 小さなBIOS+Scheduler部分は2KB程度に納まる予定で、これを二つのBANKの末尾に配置することにします。 回答が増えないのでここで締め切りとしますが、お二方にしか配点できません。AsanoNagiさん、すみません。

その他の回答 (2)

回答No.2

確か、HD64180は、Z80の拡張マイコンだったと思います。 もし違っていたら、私の回答は間違っていますので無視してください。 BANKを切り替えてもPCの値が変化しなければ、アドレスはそのまま続いていきます。 例えば、PC=0x2010の時、BANK切り替えの命令を実行するとPC=0x2012(バンク切り替え命令の命令長が2バイトの場合)となり、BANKが切り替えられます。 したがって、BANK切り替え命令を実行しただけでは、BANKが切り替わり、命令のアドレス(=PCの値)はBANK切り替え命令の次のアドレスになります。 それを避けて、BANK1にBANKを切り替えた時にBANK1の先頭からプログラムを実行したい時には、 1. BANK1にBANK切り替えしたい時に、特定のアドレスにJMPする。 2. そのアドレスでBANK1にBANKを切り替える。 3. BANK1のそのアドレスにJMP 0x0000を書いておく。 と言うことになるでしょうか。このような命令は、プログラムエリア(=ROMエリア)の末尾に書いておけばいいのではないでしょうか。

koma1000nin
質問者

お礼

確かに機種はHD64180です。 bloomers_daisukiさんの方法は、BANK-0とBANK-1の末尾に同じプログラムを置く方法ですね。そうすると、切り替え後に何らかの作業をしてから0000H番地へ飛ぶように仕組んでおけばいいということになりそうですね。 No.1さんへのお礼も参考にして下さい。

回答No.1

64180 に詳しいわけではありませんが、一般的には、「バンクメモリの中ではバンクを切り替えない」のが基本ですね。 ただ、質問の内容では、あたかも、プログラムの実行中に無秩序にバンクが切り替わるような印象ですが、一定の番地にバンク切り替えのメカニズムに相当するプログラムがあるのなら、それもありかなと思います。 通常は、バンク+飛び先を、パラメータとして受け取るようなロジックを、主プログラム側で持つでしょうけど。 バンク側でバンクを切り替えると、バンク相互の位置関係という、本来考える必要のない事項を管理する必要があるので、普通は、バンク中でバンク切り替えはしませんね。

koma1000nin
質問者

お礼

早速のご回答、ありがとうございます! 私としては、小規模のBIOSを考えていて、これに簡単なタスクスケジューラ機能を付加したかったわけで、その管理をAsanoNagiのおっしゃるとおりの姿でやりたかったのです。 やはり、バンク中でのバンク切り替えでは、複雑になるのですね!