ラベル 電子工作 の投稿を表示しています。 すべての投稿を表示
ラベル 電子工作 の投稿を表示しています。 すべての投稿を表示

2023年9月2日土曜日

NEC V60 入手

 Z80,000やZ80320と同じように入手を諦めていたのですが、たまたまネットで見つけ、ちょっと高価でしたが購入してしまいました。


同じ所でV70も販売していたのですが、V70はほとんど資料がネット上になく、入手しても走らすのは無理です。私はレトロCPUコレクターではないので、手に入れたら動かしたい派です。とは言え、入手したまま引き出しにしまったままのCPUが結構たまってきていますが。

このCPUはかなり高機能で、以下のような特徴があります。

  • 32本の32bit汎用レジスタ 
  • 浮動小数点演算命令
  • V20/V30エミュレーション
  • デマンドページングをサポートできるMMU

    詳しくは、Wikipedia https://en.wikipedia.org/wiki/NEC_V60 を参照して下さい。
    データシートがあるサイトも上げておきます。http://mess.redump.net/datasheets/nec

    V60は32bitCPUなのですが、モトローラのMC68000と同じように、データバスは 16bitになっています。アドレスバスも24bitで、MC68020のような完全な32bit CPUとはなっていません。そのため、いままで弄ってきたZ8001と同じくらいの配線量で動かせるはずです。この点が自分には結構重要で、Z8000のボードを何枚か作ってきていますが、はんだ付けやラッピングで配線して作るのは、16bitが限界だと感じています。

    趣味に使える時間は限られるので、Z8000をいじりつつ気分転換がてら少しずつ進めたていきたいと思います。


    2023年7月29日土曜日

    Z8001MBex その1

    新しくZ8001CPUボードを作製しました。今までは、ラッピングワイヤを直接はんだ付けして配線していましたが、今回初めて、ユニバーサル基板にピンヘッダをたてワイヤラッピングで配線してみました。この方法は、ピンヘッダとICソケットとの間を配線するのが単調で根気がいります。とくにPLCCソケットは苦痛でした。ラッピングでの配線はやっていて楽しいのですが、間違いに気づいたときは修正が大変です。ほどきたい配線の上にすでに配線されていると、それもほどかないといけません。一度ほどくとワイヤが傷んでしまっているので、2回目巻きなおすと折れたりするので気を使います。年で眼も弱ってきているので、そろそろPCBが作れるようにならないとだめですね。


    今回のボードは、MMUを搭載しCP/M-8000以外のOSも移植することを考えています。初代のボードでは、Z8010 MMUを使ってメモリー管理ができるように考えていたのですが、何故かうまく動作せず。結局、CPLDでセグメントアドレスを変換するロジックを組んで、CP/M-8000が動作するようにしました。しかし、この方法ではアドレス変換が固定で融通が利かず、CP/M-8000以外のOSを動かすのは難しくなります。

    新しいボードでは、Z8010を使うことは諦めて、MMUを自前で組むことにしました。これに先立って、Z8002 CPUを使ったボードで、MMUを自作できそうか簡単な回路を組んで試してあったのですが、実際に作ってみると配線量の多さからかなり苦戦しました。MMU以外は、最初のボードとほぼ同じです。

    自作MMUの仕様は下のようになっています。

    • 高速SRAMを使ってページテーブルを構成する
    • ページテーブルをメモリ空間に置く
    • ページサイズ 2Kバイト
    • 論理アドレス空間 1Mバイト(16セグメント)
    • 物理アドレス空間 1Mバイト
    • 命令とデータ空間を分離可能
    • システムとノーマルで空間を分離可能
    手持ちで256kビットの高速SRAMを持っていたので、これを使ってページテーブルを構成しました。試験的に作ったZ8002ボードでは、I/O空間にページテーブルを置いたのですが、Z8001ではメモリ空間に置くことにしました。ページテーブルはSRAMの一部しか使わないので、未使用の部分が通常のメモリとして使えます。
    また、メモリ空間だとブロック転送命令が使えるので、ページテーブルのコピーや移動が短いコードで行なえます。

    ページサイズとアドレス空間のサイズは適当に決めたもので、これが最適なのかはわかりません。欲張ると配線量が増えるので、自作するには、これ位がちょうど良いかなと思っています。

    命令とデータ空間の分離は、CP/M-8000を動かすためには必要な機能です。また、Z8001には8086のように8ビット命令がないため、コードが大きくなりがちです。64kバイトのセグメントサイズに縛られるZ8000では、データを別空間に置ける機能はあったほうが良さそうです。

    システムとノーマルで空間を分離する機能は、UNIXのようなOSを移植するために付けておきました。一応、CP/M-8000でも使われているようなのですが、役には立っていないようです。

    今回は次のような機能は見送っています。
    • ページを無効に設定できる
    • ページを書き込み禁止に設定できる
    • ページにアクセスがあったか記録する
    最初の2つは、あとからでも実装できると思います。しかし、ページアクセスの記録は、別のメモリを積むか、高速SRAMにアドレス変換後に書き込む回路を追加する必要があり、実現が難しいので諦めています。

    すでに、CP/M-8000の移植は完了しています。初代のボードとほとんど同じなので、MMUの初期化を追加し、初代のボードと同じセグメントアドレス変換になるよう合わせれば動きました。

    そして今、UNIX V7を移植しようと挑んでます。

    2021年12月27日月曜日

    Z8K CP/Mボード その2

    こんなものを試す人はかなりのハッカー基質の人だと思い、Githubの説明はあまり親切でないのと、英語があまりにひどいので、CP/M-8000を起動させるための補足をしておきます。

    準備

    作業はDebian系のディストリビューションで行うことを想定しています。ATMEGAのコードをビルドし書き込むために、gcc-avr, avr-libc, avrdude をインストールしておきます。Z8000のコードをアセンブルするために、GNUのサイトからbinutils をダウンロードして、 Z8001クロス開発環境 binutilsをビルドしてみるを参考にビルドしてください。私が確認しているは使っているのは、binutils-2.34 です。

    ATMEGA164のヒューズビット設定 

    Z8001MBと同じくZ8K CP/Mでは、Z8001を起動するためにATMEGA164Pが使われていますが、JTAGの禁止と外部クロック入力にするためヒューズビットの書き換えが必要です。値は、LFUSE : 0xE0, HFUSE : 0xD9 です。ATmega164PのJTAGを禁止するを参照し、avrdudeを使って書き換えてください。

    マシンモニタの書き込み

    z8kboot ディレクトリでmakeを実行してください。z8kbooter.elf が作られます。 チップへの書き込みは、make write で実行できます。

    CP/M-8000のビルド

    COFFに変換済みのcpmsys.o と libcpm.a が入れてあるので、cpm8kディレクトリで、makeするだけです。cpm8k.bin が作られます。

    CP/M-8000のディスクイメージの作成

    cpmtoolsをインストールし、/etc/cpmtools/diskdefsにcpm8kディレクトリにあるdiskdefsを追加します。diska/b/c/d ディレクトリにディスクイメージに含めたいファイルを入れて、make dskimg を実行します。disk.img   ができるので、dd でCFに書き込めばOKのはずです。ディスクイメージに入れるCP/M-8000のコマンド類は、 http://www.cpm.z80.de/download/cpm8k11.zip を解凍すると得られるDISKn.ZIPに含まれています。

    こんな状況になると予想しておらず、慌てて書いたので間違っているかもしれません。

    2021年12月26日日曜日

    Z8K CP/Mボード

     私がGithubにあげているZ8001MBの回路図をもとに、tomi9さんがCP/M-8000を動作させることができるPCBを作成され、一枚送ってくださいました。


    PCBだけでなくCFのソケットとGALも同封されており、あとは手持ちの部品だけで行ける状態でした。tomi9さん、ありがとうございます。自分もいつかはPCBを作ってみたいとは思っているのですが、なかなか勇気が出ません。ラッピングワイヤーでの手配線だと、すぐに回路の修正がききますが、PCBだとそう簡単にはできません。

    久しぶり(中学高の技術の授業以来?)のPCBでの組み立てで、ちょっと一投目は緊張しましたが、最難関のCFソケットのはんだ付けを済ませ、Z8536以外の部品を組みつけて、現在、動かせるところまで来ています。

    2021年9月26日日曜日

    Z280MB 考え直して高速化

     前回、Z280MBのこれ以上の高速化はやめておくと心に決めていたのですが、なにか釈然としないのと、ASCIIARTの実行速度を収集?しているはせりんさんからのリクエストもあり、外部クロックの12MHz化を試してみることにしました。

    難しいというか面倒なのは、外部クロックを変更できるのが、リセット時にハードウェア的にのみできるということです。実際には、

    • /RESETの立ち上がりエッジで、/WAITをLowにしておく
    • AD0-AD7に初期化データを乗せておく
    • 2クロックサイクル以上、/WAITと初期化データを保持
    最初はCPLDにまだ余裕があるので、/WAITをLowに保持するロジックを組み込もうと考えていたのですが、よく考えたら/RESETから適当にCRディレイ回路で/WAITを作れば良いと思いつきました。

    問題は、2クロックサイクルが何のクロックサイクルかだったのですが、結局CLKピンからの出力2クロックサイクルのようです。データシートからは、外部入力クロックのXTALIのように読み取れるのですが、これに合わせると初期化できませんでした。長さは検証していないのですが、2クロックサイクル以上ならどうでも良いようです。

    リセット回路にCRディレイ回路を付け足したのと、写真の赤線で囲んだところに、AD0-AD7に初期化データが乗せられるようにDIPスイッチとバッファが付け足してあります。

    実行結果は、外部クロック6MHzから30秒ほど縮めて、1分33秒まで高速化できました。まあこれなら納得できます。



    2021年9月5日日曜日

    Z280MB ASCIIART(マンデルブロ集合)を実行してみて思うこと

     Z280MBにCP/Mを移植できたので、この界隈で試す人の多いASCIIARTを試してみました。


    実行環境は、内部クロック12MHz / 外部クロック6MHz / MBASIC rev.5.21です。

    結果は、キャッシュONで2分38秒、キャッシュOFFで5分11秒でした。結果をTwitterにあげたところ、Electrelicさんからリフレッシュを止めるともうちょっと速くなるとアドバイスをもらい試したところ、2分8秒まで改善しました。Z280MBはDRAMを使っていないので、リフレッシュは不要なのですが、こんなにリフレッシュサイクルが負荷になるとは思ってもいませんでした。

    参考にさせてもらったElectrelicさんの記事はこちらです。Z280固有の初期化(その1)

    結果は、はせりんさん 番外編:ASCIIART(マンデルブロ集合)ベンチマーク に掲載されたのですが、他のZ80系CPUに比べてお世辞にも速いとは言えません。同じクロックだと、確実に高速版Z80やHD64180に負けるでしょうし、キャッシュOFFの結果は悲惨です。

    これ以上の高速化は、外部バスクロックの12MHz化とバーストモードを使うことが必要ですが、ハードウェアの改造や新規設計が必要になるのでやめておきます。

    Z280には、ユーザ/システムの分離とか仮想メモリが可能なMMUとかI/D分離とか、他にも面白い機能があるので、浪漫あふれた古の石ということで良いのではないでしょうか。

    CP/Mの次はFUZIXを移植してみたいと思っています。

    Z280MB CP/Mを移植

    ここしばらく、Z280MB に CP/M を移植していました。移植したバージョンは 2.2 です。EDでコードを書きASMでアセンブルできることを確認しています。

    CP/M-8000 の移植は経験済みだったので、大して難しくないのかなと思っていたのですが、ディスクアクセス周りで苦戦して結構時間がかかってしまいました。かなり悩んだすえ、結局使っていたコンパクトフラッシュカードの問題だったようなのですが、おかげで、8-bit から16-bit PIOモードにコードを書き換えたりできたので良しとします。ディスクアクセスのブロッキング・デブロッキングは思いっきり手抜きです。気が向いたら書き換えることにします。

    CP/M-8000と違って、CCPがコマンドで上書きされたり、メモリーの配置が全然違ったりで最初とまどったのですが、ネット上に情報が豊富にあり助けられました。今回の移植作業で、参考にしたサイトを上げておきます。

    pineconeの電子工作 

     BIOSの作成過程が楽しく詳しく語られています。非常に参考になりました。

    nekoJavaさんのCP/Mコーナー

     CP/M-8000のときも参考にさせてもらいました。CP/Mど素人の私にはありがたいサイトです。

    Grant's homebuilt electronics

     コンパクトフラッシュをつなぐのに参考にさせてもらっています。

    移植の成果は、Github にあげておきました。CP/Mのライセンスの関係でBIOSのソースコードのみを上げることにしました。BIOSをアセンブルし、できたバイナリをCPM.SYSと結合するMakefileとディスクイメージを作るシェルスクリプトを入れておきました。

    まあ、試す人はいないと思いますが。


    2021年7月24日土曜日

    Z280MB CFカードを接続と回路図公開

     Z280MBにCFカードを接続できるように拡張しました。Z8002MBで作ったIDEインターフェースボードをそのまま流用し、その先にIDE-CF変換アダプタを接続しています。


    CFカードのセクター読み書きができることは確認できているので、まずはCP/Mを移植してみようと思っています。

    ハードウェアは一段落したので、GitHubに回路図を上げておきました。これを見て作ろうとする酔狂な人はいないとおもいますが。

    Z280MB GitHubリポジトリ


    2021年6月19日土曜日

    Z280MB 起動する

    Z280 MPU Boardは、はんだ不良などでかなり苦戦していたのですが、安定して動作するようになりました。

    現在は簡単なマシン語モニタが動作しています。

    • メモリダンプ
    • メモリ書き換え
    • ジャンプ
    • インテルHEXファイルのロード
    の必要最低限のことしかできませんが、EEPROMの書き換えが必要なくなり、だいぶ作業が楽になります。これからは、このモニターでテストコードを走らせながら、Z280特有の機能を試していきたいと思います。


    その先にはボードを拡張して、CP/M や FUZIX を移植してみたいとも考えています。

    2021年5月19日水曜日

    Z280MB 組み立て

     GWを目一杯使って、Z280ボードを組み立てました。


    16bit CPUは配線量が多く、老眼が進んできている自分にはかなりきついです。特にPLCCソケットのピンへのはんだ付けは、線同士が重なるので見づらくて正直あまり好きではありません。よく順番を考えながらはんだ付けしていかないと、あとで後悔します。白のラッピングワイヤがデータバス、オレンジがアドレスバス、青がバス制御とその他の信号ラインです。


    ユニバーサル基板で作るのは、自分にはそろそろ限界なのかもしれません。次回はPCBを起こせるようになりたいものです。

    このMPUボードは、CPUクロックが12MHz、SRAMが256kバイト、EEPROMが16kバイトの構成です。ROMは実際には2Mビット×2なのですが、そんなにもいらないので、16kバイト分だけ使えるようにしてあります。リセット直後は、64kバイトのメモリ空間にはROMしか現れず、MMUをつかってアドレス上位に置かれているSRAMをマッピングして使えるようにします。

    現状では、UARTから”hello world"が出力できているレベルで、MMUなどの確認はできていません。回路図は動作が確認できたら公開するつもりです。



    2021年5月2日日曜日

    Z280のZ-BUS

    当初、Z280を8-bitのZ80-Busで動かそうと思っていたのですが、はんだを始めたら調子が乗ってきたのと、あとで変更するのが結構面倒なことに気づいたので、はじめから16-bitのZ-BUSで行くことに変更しました。


    Z-BUSでもアドレスとデータバスはマルチプレクスされているので、アドレス用の8-bitラッチが2個必要になります。
    データバスの接続は、偶数番地がAD15-AD8に、奇数番地がAD7-AD0になります。バイトリードの場合は、Z280がAD15-AD0の上位と下位を選んでデータを読み込んでくれますが、バイトライトの場合は、AD15-AD0の上位と下位には同じデータが出されますので、A0で書き込むメモリチップを選択をする必要があります。ワードのリードライトでは、Z280がリトルエンディアンなので、上位と下位を入れ替えてくれます。

    B/Wはバイトかワードアクセスを示し、R/Wはリードかライトを示します。/DSはデータの読み書きのタイミングをとる信号です。Z8000のZ-BUSと違うところは、メモリアクセスを示す/MREQがありません。ST3-ST0をデコードしてメモリアクセスかを判断する必要があり、1000と1001の場合がメモリアクセスを示します。

    Z-BUSでのメモリアクセスのタイミングは下図のようになっています。Z8000と同じです。

    2021年4月19日月曜日

    Z280のクロック

     Z280のクロックは少し複雑です。チップからは、XTALI, XTALO, CLK の3本もクロック関係のピンが出ています。

    Z280は内部にクロックオシレータを持っており、水晶振動子をXTALIとXTALOにつなぐか、XTALIに外部からクロック信号を入れると動作することになっています。内蔵オシレータからのクロックは1/2に分周され、CPUクロックになります。今手持ちのCPUは12MHz品なので、クロックは24MHzまで入れることができます。

    外部バスのクロックは、CPUクロックを更に1/2, 1/4分周にすることができ、CLKピンから出力されます。デフォルトでリセット後は1/2にセットされるのですが、この分周比は、データシートによるとソフトウェアからでは変更できません。

    これは、アクセススピードが遅いメモリやI/Oを接続することを考慮したものなのでしょうが、Z280を最速で動かすには、バスクロックをCPUクロックと同一にする必要があります。厄介なことに、この分周比を変更できるのは、リセット時にデータバス経由で値を渡す方法だけのようです。

    2021年4月10日土曜日

    Z280のZ80-Bus

     

    Z280のZ80 Busですが、その名前と違い、メモリやI/Oと接続するための信号やタイミングはZ80とは完全に同じではありません。8-bitバスという点では同じなのですが。


    データD0-D7とアドレスA0-A7は、AD0-AD7としてマルチプレクスされているので、アドレスを保持するためにZ8000と同じようにアドレスラッチが必要です。/ASは、AD0-AD7がアドレスを出していることを示す信号です。
    /OEと/IEは、ADが出力か入力を示す信号で、ちょっと使いみちが思いつきませんが使わなくても大丈夫そうです。

    Z80と違い、命令のフェッチでもデータのリードライトでも同じタイミングで行われます。

    メモリリードでは、/MREQがLになり、続いて/RDがLになります。データはT3の立ち下がりで読み取られます。

    メモリライトでは、/MREQがLになり、AD0-AD7にデータが出力され、続いて/WRがLになります。

    よくある非同期バスなので、スタティックメモリをつなぐだけなら大して難しくはなさそうです。

    I/Oアクセスは、タイミングは違えどメモリとほぼ同じようです。Z280には主要な周辺I/Oが組み込まれているので、I/Oアクセスの事はしばらく忘れておきます。


    参考文献 
     Z280 PRELIMINARY Technical Manual
     Z280 Product Specification

    2021年4月3日土曜日

    Z280のリセット

    Z280の資料を読み始めました。まずはリセットあたりから。

    Z280のリセットは少々複雑です。 ハードウェアリセットは、/RESETピンを128クロックサイクルの間、Lにすることでかかります。 
    外部バスをZ-BUSかZ80 Busにするかは、このリセット時にOPTピンで決定します。

     Z80 Bus --- opt = L 
     Z-BUS ----- opt = H or NC

    /RESETピンをHに戻すときに、/WAITピンがLになっているとAD0-AD7ピンからデータを読み込んでBus Timing and Initialization Register を初期化できます。AD6をHにしておくとブートストラップモードになり、リセット後にUARTから256バイト読み込んで実行します。ROMレスなシステムを作るの使う機能で面白そうですが、スタンドアロンで動作できなくなってしまうので、今回は使わないつもりです。
    他にも、メモリアクセス時のウエイト数を設定したり、外部バスクロックの設定ができたりするのですが、初期化に余分な回路が増えるため、この初期化方法は使わないことにします。

    /RESETがLになっている間は、AD0 - AD15, A16 - A23 はHi-Z で、他の制御出力ピンはHになります。

    参考文献 
     Z280 PRELIMINARY Technical Manual
     Z280 Product Specification

    2021年3月30日火曜日

    Zilog Z80280

     Z8000へのPCC移植がちょっと行き詰まってしまい、気分転換にはんだ付けがしたくなってきました。今回の目標はZilog の Z280を動かすことです。


    この石は中国から購入したのですが、ほんまもんなのかがわかりません。時間かけたあげく無駄に終わる可能性もあります。前回のZ8002も中国から購入したのですが、(本当に10MHz品かは別として)こちらは動作しました。偽物を掴まされてたとしても、それはそれで楽しいので、手をつけてみます。

    Z280は、Z80とコードレベルで互換性がある16bit CPUです。単純にCPUなわけではなく、MMUやDMA、タイマ、シリアルポートなどを集積したかなり豪華な構成になっています。メモリスペースはMMUを通して、64kByteから16MByteまで拡張されています。外部バスは、16bitのZ-BUSモードか8bitのZ80 Busを選べるようになっています。

    もちろん、Z280の性能を活かし切るにはZ-BUSで使うことになるのですが、配線量が増えるし、偽物だったときの精神的ショックを抑えるため、まずはZ80 Busで動かしてみたいと思います。


    2020年9月30日水曜日

    Z8530 SCC

     Z8530 SCCを制御するコードも上げておきます。

    先ずは初期化のコードです。送受信の割り込みが処理できるように初期化しています。この石もかなり曲者で初期化手順を間違うとうまく動きません。

    発生させる割り込み込みベクタは0x10からで、チャンネルAの送信が0x18で、受信が0x1cになります。

    	.equ	SCCAC, 0x0009
    	.equ	SCCAD, 0x000D
    
    init_scc:
    	ld	r2, #(scccmde - scccmds)	! initialize Z8530
    	ld	r3, #SCCAC
    	ld	r4, #scccmds
    	otirb	@r3, @r4, r2
    	ret
    
    scccmds:
    	.byte	9, 0xc0		! Reset
    	.byte	4, 0x44		! x16, 1stop-bit, non-parity
    	.byte	3, 0xe0		! Receive  8bit/char, rts auto         
    	.byte	5, 0xe2		! Send 8bit/char, dtr rts
    
    	.byte	2, 0x10		! Interrupt vector
    	.byte	1, 0x12		! Interruprt on Rx All character and Tx Int
    	.byte	9, 0x09		! MIE, VIS, Status=Low 
    
    	.byte	11, 0x50	! BG use for receiver and transmiter
    	.byte	12, 30		! 4800bps at 5MHz clock
    	.byte	13, 00
    	.byte	14, 0x02	! PCLK for BG
    	.byte	14, 0x03	! BG enable
    
    	.byte	3, 0xe1		! Receiver enable
    	.byte	5, 0xea		! Transmiter enable
    
    scccmde:
    

    割り込みハンドラーは、次のようなコードです。リングバッファ処理部分は端折ってあります。Z8536と同じで割り込み処理の終了処理を正しく行わないと、優先順位の低い割り込みがかからなくなったりします。

    scc_rxint:				! Rx InterruptHandler
    	push	@r15, r0
    	push	@r15, r1
    1:	
    	inb	rl0, #SCCAC
    	andb	rl0, #0x01
    	jr	z, 1b 
    	inb	rh0, #SCCAD		! Read a data from Rx buffer
    	
        !
    	!
        
    	ldb	rl0, #0x38		! Enable IUS
    	outb	#SCCAC, rl0
    	pop	r1, @r15
    	pop	r0, @r15
    	iret
    
    scc_txint:				! Tx Interrupt Handler
    	push	@r15, r0
    	push	@r15, r1
    
    	!
        !
        
    	outb	#SCCAD, rl0 ! Write a data to Tx buffer
    	
    	ldb	rl0, #0x28		! Clear Tx interrupt pendinng 
    	outb	#SCCAC, rl0
    	ldb	rl0, #0x38		! Enable IUS
    	outb	#SCCAC, rl0
    	
        pop	r1, @r15
    	pop	r0, @r15
    	iret
    

    2020年9月12日土曜日

    Z8536 CIO

     Z8536の初期化手順と割込み処理のメモです。カウンタタイマ3で10mS周期の割り込みをかけます。

    Z8536にはRESETピンがなく、ハードウェアリセットはRDピンとWRピンを同時にLにすることで行います。今回はハードウェアを手抜きしているので、ソフトウェアでリセットしています。A0, A1ピンをHにしてリードし、つづいて、レジスタ0に1を書き込んだのちレジスタ0に0を書き込みます。これで初期化されます。

    レジスタのアクセスは、A0, A1ピンをHにしアクセスするレジスタ番号を書き込み、つづいて目的のレジスタに書き込みか読み込みをします。Z8536を初期化するのにレジスタ設定の順番を変えたりすると、なぜか動かなくなったりします。正しい手順はよく理解できていないのですが、手探りで見つけた手順が下のコードです。


    	.equ	CIOPRTC, 0x0011
    	.equ	CIOPRTB, 0x0015
    	.equ	CIOPRTA, 0x0019
    	.equ	CIOCTRL, 0x001d
    
    
    init_cio:
    	ld	r1, #CIOCTRL
    	inb	rl0, #CIOCTRL
    	lda	r2, ciocmds
    	ld	r3, #(ciocmde - ciocmds)
    	otirb	@r1, @r2, r3
    	ret
    
    ciointr:
    	push	@r15, r0	! レジスタ保存
    	push	@r15, r1
    
    	! 割り込み処理
    	!
    	!
    	
    	ldb	rl0, #0x0c
    	outb	#CIOCTRL, rl0
    	ldb	rl0, #0x24
    	outb	#CIOCTRL, rl0	! Clear IP and IUS
    	
    	pop	r1, @r15	! レジスタ復帰
    	pop	r0, @r15
    	iret
    
    !------------------------------------------------------------------------------
    
    ciocmds:
    	.byte	0x00, 0x01		! Reset
    	.byte	0x00, 0x00		! Clear reset
    	.byte	0x01, 0x00		! Reset PortC and C/T3
    	.byte	0x01, 0x10		! Enable PortC and C/T3
    	.byte	0x1e, 0xc2		! Continuous, Ext Output, Square wave
    	.byte	0x1a, 0x30		! Set timer constant
    	.byte	0x1b, 0xd4		! Set timer constant
    	.byte	0x00, 0x84		! MIE and VIS
    	.byte	0x04, 0x00		! Set Interupt vector
    	.byte	0x0c, 0xc0		! Set Interupt Enable bit
    	.byte	0x0c, 0x06		! Gate and Triger
    ciocmde:
    


    割り込み処理は、最後にレジスタ12のIPとIUSをクリアして戻れば、続けて割り込みが発生します。これを忘れると、割り込みが単発になったり、他のチップからの割り込みが発生しなくなります。

    Z8530もそうでしたが、Zilogの周辺チップはプログラムが難しい印象です。さらにデータシートが不親切で、読んだだけでは理解できないことが多々あります。ネット上にもあまり情報がないので、手探りがで動かすことになるのですが、動いた時の高揚感は格別です。

    2020年9月6日日曜日

    Z8002にMMUを その3

    今回作成したMMUの回路図が下です。

    高速SRAM, マルチプレクサ、双方向バッファ、CPLDからなっており、CPLDが各ICの制御信号を作っています。TTL-ICを組み合わせて制御信号を作るのは面倒なのと、うまく動かなかったときに、CPLDだと回路の変更をせずにロジックを書き換えるだけで対処できます。

    CPLDの定義ファイルのMMUに関連する部分の抜粋です。
    IOREQ = ST0 # !ST1 # ST2 # ST3;
    
    DI = !ST3;
    MMUSEL = !A15 # !A14 # IOREQ;
    MAPSEL = MMUENA & MMUSEL;
    MMUBUFE = MMUSEL # DS;
    MAPRD = (MMUSEL # !RW # DS) & !IOREQ;
    MAPWR = MMUSEL # RW # DS;
    1個のCPLDでメモリアクセス用の信号も作ったりしているので、I/Oをほぼ使い切ってしまっています。
    アドレスマップの高速SRAMは、I/O空間でアクセスでき読み書きができます。アドレスは次のようになっています。

    - no title specified

    I/O Addr

    N/S

    D/I

    Page No.

    C001

    S

    I

    0

    :

    :

    :

    :

    C01F

    S

    I

    F

    C021

    N

    I

    0

    :

    :

    :

    :

    C03F

    N

    I

    F

    C041

    S

    D

    0

    :

    :

    :

    :

    C05F

    S

    D

    F

    C061

    N

    D

    0

    :

    :

    :

    :

    C07F

    N

    D

    F

        
        
    S --- System, N --- Normal (User), D --- Data, I --- Instruction

    システムがリセットした時には、アドレスマップを初期化したのちMO端子をアクティブにすることでMMUが機能します。それまでCPUは、RAMの先頭ページ(4kバイト)しかアクセスできません。

    2020年7月30日木曜日

    Z8002にMMUを その2

    今回作るMMUは、高速SRAMをマッピングテーブに使った回路になり、下の図のような構成になります。


    Z8002のアドレス下位12ビットは、そのまま物理アドレスの下位12bitとしてメモリに渡します。Z8002のアドレス上位4bitは高速SRAMのアドレスに入れ、読み出されるデータ8bitを物理アドレスの上位8bitとします。これで合計20bit( 1Mバイト分)のアドレスに変換します。

    アドレス変換を行うには、高速SRAMにマッピングデータを書き込む必要があるので、マルチプレクサとバッファをつけます。高速SRAMは0xC000からのI/O空間に置きアクセスします。マルチプレクサは、変換する仮想アドレスの上位4ビットとI/Oアクセスするアドレスを切り替えるために使います。バッファは、高速SRAMをデータバスに接続するために必要です。

    本当は、アドレスの上位4ビットをバイパスするために、高速SRAMとメモリの間にさらにマルチプレクサを追加したいのですが、部品と配線量が増えるので見送ります。これはCPUリセット後に高速SRAMを初期化するまでの間、MMUを無効にしておくために必要なのですが、単純に高速SRAMを非アクティブにしおいて データバスをプルダウンすることにします。このため上位8ビットが0に固定され、MMUが初期化されるまでの間はメモリの先頭の4kバイトしかアクセスできなくなってしまいます。

    いま気づいている点は、
    • ページがマップされていない状態を設定できない
    • ページごとに書き込み禁止を設定できない
    • ページに書き込みがあったか記録できない
    などですが、実現するには高速SRAMを追加する必要があります。これらの機能がどれくらい必要なのか判断がつかないので、MMUは最小限の構成にしておいて、とりあえず動かすことを優先します。


    2020年7月12日日曜日

    Z8002にMMUを その1

    MMUについて考えていきます。

    Z8001にはZ8010というMMUが準備されていますが、Z8002にはつなげられないため、必然的に自作することになります。今回はUNIX V6を動かそうとしているので、DECのPDP-11のメモリ管理機構を参考にします。ネットの情報と「はじめてのOSコードリーディング」を読んだところでは、ざっと下のような感じです。
    • 64kバイトの物理アドレスは、8つのセグメントに分割されている
    • セグメントの最大サイズは8kバイト
    • 各セグメントは、64バイト単位でサイズが可変できる
    • 各セグメントは、物理アドレスの64バイト境界にマップできる
    • カーネルとユーザで空間を分離できる
    • 命令とデータの空間が分離できる
    • セグメント毎に読み込み専用に指定できる
    完全に同じものを作るのは難しそうなので、次のように単純化します。
    • セグメントサイズは固定
    • セグメントの物理アドレスへのマッピングはセグメントサイズ境界に揃える
    • 読み込み専用指定は実装しない
    • カーネルとユーザで空間は分離する
    • 命令とデータで空間は分離する
    セグメントのサイズは、4kバイト固定にします。マッピングテーブルに高速SRAMを使ったアドレス変換回路を組むのですが、高速SRAMのデータバスは8ビットなので、セグメントサイズを4kバイトにすると、上位8ビット + 下位12ビットでちょうど1Mバイトのメモリを扱うことができます。

    セグメントのマッピング位置をセグメントサイズ境界に揃えると、メモリの使用に無駄が多くなりそうですが、PDP-11のように細かくしようとするとセグメント情報を記録するマップが大きくなってしまいます。また、加算回路が必要になるためアドレスが確定するまでの遅延が大きくなり配線量も増えるので諦めます。その分、セグメントサイズを4kバイトに小さくすることにします。

    読み込み専用指定は、テキストセグメントへの書き込み禁止などの保護のために使うのでしょうか。今回は設定できなくても特に問題はないと思うので省略します。

    カーネルとユーザ空間の分離は、Z8000がシステムとノーマルモードを持っており、どちらで動作しているか信号を出しているので実装できそうです。

    命令とデータの空間分離は、Z8000では64kバイトしかアドレス空間がないので、プロセスが使えるメモリを増やすために有用です。これも信号が出ているので実装してみます。