SFD-700 マルチホスト フロッピーディスクコントローラ
2024年2月アップデート - v1.2ハードウェアは完全に動作しており、EXT700アダプターを使用して私のMZ-80A、MZ-700、MZ-1500、およびMZ-2000拡張ユニット内でテスト済みです。MZ-1U06での使用で問題が報告されており、調査が必要です。CPLDタイミングの問題のようです。CPLDロジック(VHDL)は完成しており、すべてのROM/RAMページングおよびホストモードロジックが正常に動作しています。SFD-700に移植されたROMファイリングシステムソフトウェアは基本的なFDC操作(「F」コマンドによるフロッピーブート)には対応していますが、フロッピーディスクモニターツールの完全なセットはまだ含まれていません。継続的に開発中です。クライアント業務により進捗が遅れています — 最新状態についてはGitHubリポジトリをご確認ください。他のMZシリーズマシンでのボードテストはまだ実施していませんが、適宜行う予定です。
Sharp MZシリーズで最も必要とされるアクセサリーの一つが、由緒あるフロッピーディスクコントローラーです。Sharp MZ時代には主にコストの問題から使用する人が比較的少なく、入手困難です。
Sharpは複数のフロッピーディスク拡張カードを設計・発売しました。MZ-2500/2800/3500/5600/6500シリーズのように本体内蔵のものも、プラグインカードが必要なものもありました。最初はMZ-80Kシリーズ内のカスタムコントローラーから始まり、MZ-80Bビジネスマシンの登場とともにSharpはWestern Digitalフロッピーディスクコントローラーアーキテクチャを標準化し、独自コントローラーIC「MB8866」を設計・製造しました。
MZ-80Bの設計では、すべてのフロッピーディスク制御ファームウェアがマシンのIPL(Initial Program Loader)に格納されることを前提としており、これはMZ-800/MZ-1500/MZ-2000/MZ-2200の設計にも引き継がれ、これらの新しいマシンとのコントローラー互換性を維持しました。
残念ながら、MZ-80A/MZ-700などの下位モデルでは、設計段階でフロッピーディスクが考慮されておらず、必要なフロッピーディスクブートストラップファームウェアを提供するためにオンボードROMを備えた新しいコントローラー拡張カードの開発が必要でした。さらに、MZ-80Aは2MHzで動作するため、DRQフラグを確認して安定したストリームでデータを読み込むのに十分な速度がなく、SharpはDRQラインがROMアドレスラインを切り替えてデータフローを処理するための処理速度を向上させる必要がありました。
Sharpのフロッピーディスク拡張カードは高価だったため、より安価な製品を提供するサードパーティーの機会が生まれました。ドイツのK&P Partners GmbHという会社がそのような会社の一つで、MZ-80B/MZ-1500/MZ-2000/MZ-2200ホストにも対応したMZ-800用のSFD-800と、MZ-700を対象としたSFD-700の2製品を提供していました。
最初はSFD-800と同様にレプリカ設計を考えましたが、様々な回路を調べた結果、K&P SFD-700にはメモリーページングという致命的な欠陥があることがわかりました。このカードはMZ-700のページング状態レジスタに基づいて拡張カードメモリへのアクセスを無効にするページングロジックを持つMZ-1U06拡張ユニットで動作するように設計されていました。カスタム拡張ユニットで使用すると動作しませんでした。またMZ-80Aにもフロッピーコントローラーが必要だったため、MZ-80A以降のすべてのMZシリーズ(内蔵コントローラーを持つものを除く)で動作する1枚のカードが最善策だという結論に至りました。こうしてSFD-700 mkIIのコンセプトが生まれました。K&P製品と同じ名前ですが、より多くの機能を持ちます。
このドキュメントでは新しい回路図、プログラマブルロジック、各マシンで発見された問題を説明します。
ホスト互換性
SFD-700 v1.2はMZ-80A以降のすべてのSharp MZシリーズマシン(内蔵フロッピーコントローラーを持つマシンを除く)をサポートします。対象ホストはリセット時にラッチされるPCB上の3ビットMODEジャンパーで選択します。以下の表にサポートされているマシンと対応するジャンパー値を示します。
| MODE | ホストマシン |
|---|---|
| 0 | Sharp MZ-80A / MZ-1200 |
| 1 | Sharp MZ-700 |
| 2 | Sharp MZ-80B |
| 3 | Sharp MZ-800 |
| 4 | Sharp MZ-1500 |
| 5 | Sharp MZ-2000 |
| 6 | Sharp MZ-2200 |
MZ-80A/MZ-1200では、CPUが2MHzで動作するためWD1773のDRQフラグをポーリングして次のバイトが到着する前にデータレジスタを読み込むのに不十分です。CPLDはDRQ信号をフラッシュROMアドレスビットA10に接続することでこれを処理し、各1KBセグメントに重複したファームウェアコードが現れるようにします。これによりソフトウェアポーリングが不要になり、DRQラインがROMブートストラップの正しい読み込みまたは待機パスを直接選択します。
回路図

プログラマブルロジック
v1.0 / v1.1 — GALベース設計
初期リビジョンでは2つのGALデバイスを使用していました。Lattice GAL26CV12をI/OアドレスデコーダーおよびメインのMZ-700メモリ管理コントローラーとして、Lattice GAL16V8をROMアドレスデコーダーおよびホストモードセレクターとして使用しました。設計はCUPL(Compiler for Universal Programmable Logic)で記述され、オリジナルのLogical Devices CUPL v4.0ツールチェーンでコンパイルされました。
GAL26CV12が選ばれたのは、広いI/Oアドレス範囲をデコードしてMZ-700メモリーページング状態を管理するための十分なプロダクト項と登録済み出力が備わっており、標準の16V8または22V10では対応できなかったためです。残念ながら、26CV12には2つの実用上の問題がありました。まず、ツールサポートの問題:MicrochipがAtmel(Logical DevicesとCUPLツールチェーンを取得していた)を取得した際に、後継製品のWinCUPLはAtmel互換デバイスのみをターゲットとするよう更新され、Lattice 26CV12のサポートが削除されました。v1.0/v1.1のコンパイルには、WinCUPLではなくオリジナルのDOS時代のCUPL v4.0または同等のツールチェーンが必要です。次に、プログラマーサポートの問題:TL-866 II+などの現行の市販プログラマーは、PLCC-to-DIPアダプターとMinipro用のカスタムデバイス設定ファイルなしには26CV12をサポートしていません。
これらの問題にもかかわらず、v1.0とv1.1はMZ-700での基本的なフロッピー操作に対して動作していました。しかしGAL26CV12のレジスター数が制限的な制約でした。デバイスには登録済み出力クラスターが1つとリミテッドなエキスパンダープールしかなく、完全なMZ-700メモリ管理状態追跡とROMファイリングシステムに必要な独立したROM/RAMページレジスターを同時に実装することが不可能でした。これがv1.2がCPLDに移行した主な理由です。
v1.2 — CPLD(VHDL)
バージョン1.2では両方のGALデバイスを単一のAltera MAX7000S EPM7128SLC84-15 CPLD(PLCC-84、128マクロセル)に置き換え、VHDLで実装してQuartus II 13.0.1 SP1でコンパイルしました。これによりGAL26CV12のレジスター数の制限が解消され、2つのメモリウィンドウにわたる独立したROM/RAMページングとともに完全なMZ-700/MZ-1500メモリマッピングロジックが実現しました。VHDLソースファイル(
sfd700.vhd、sfd700_Toplevel.vhd、sfd700_pkg.vhd)はGitHubリポジトリのCPLD/v1.2/ディレクトリにあります。v1.0/v1.1の旧CUPLファイルは参照のためにCUPL/ディレクトリに残されています。
GAL(v1.0 / v1.1)
デバイス
2つのLattice GALデバイスがv1.0およびv1.1ボードのすべてのプログラマブルロジックを実装しています。GALデバイスはEEPROMベースのPLD(プログラマブルロジックデバイス)で、ヒューズアレイにSum-of-Productsロジックを実装し、組み合わせ論理と登録済み(フリップフロップ)出力の両方をサポートします。後のCPLDとは異なり、各GALは単一レベルのデバイスです。デバイス間のルーティングファブリックがないため、両方のGALにまたがる必要のある信号はPCB上でルーティングする必要があります。
| デバイス | パッケージ | マクロセル | 登録済み出力 | 役割 |
|---|---|---|---|---|
| GAL26CV12 | 28ピンDIP | 12 | 12 | I/Oデコーダー、FDC制御、MZ-700メモリ管理 |
| GAL16V8 | 20ピンDIP | 8 | 8 | ROMアドレスデコード、モード選択、DRQマルチプレクサー |
GAL26CV12(
8つのアドレスライン(A0〜A7)がIORQn、RDn、WRnの制御入力と組み合わされ、各レジスターアクセスを識別します。WD1773 FDCレジスターブロックに対して別々の読み込みと書き込みセレクトが生成され、双方向バスバッファーを正しい方向に切り替えられます:IOBUSDIRnはFDCの読み込み時のみロー(Z80→FDC方向)になり、FDCnチップセレクトは読み込みと書き込みの両方でアサートされます。 FDCペリフェラル制御
0xDC、0xDD、0xDEへの書き込みにより、PCB上のドライブ選択、ヘッドサイド、データ密度ラッチをクロックするシングルサイクルストローブ出力(DRIVEn、SIDEn、DDENn)が生成されます。FDCRESETn出力はZ80 RESET信号に直接接続されており、システムの電源投入またはハードウェアリセット時にWD1773が常にリセットされます。 MZ-700メモリ管理
MZ-700はI/Oポート0xE1〜0xE6への書き込みを使用して内部DRAMとCGROMを上位アドレス空間にバンク切り替えします。GALはデコードされたポートストローブでクロックされた登録済み出力を使用して2つの独立した状態ビットを追跡します:
INTEN登録済み出力はポート0xE7へのアクセスから生成されるINTCLKストローブでクロックされます。書き込みで有効が設定され(INTEN.DはWRnに従う)、読み込みでクリアされます。INTENはシステムのRESET入力で非同期リセットされます。INTCLK出力はPCB上の外部フリップフロップのクロック入力にフィードされます。
SFD700_GAL1)はプライマリロジックデバイスです。Z80 I/OアドレスバスをデコードしてすべてのFDC制御信号を生成し、双方向データバスバッファーを管理し、MZ-700メモリーページング状態を追跡し、割り込み有効フラグを制御します。
I/Oアドレスデコード8つのアドレスライン(A0〜A7)がIORQn、RDn、WRnの制御入力と組み合わされ、各レジスターアクセスを識別します。WD1773 FDCレジスターブロックに対して別々の読み込みと書き込みセレクトが生成され、双方向バスバッファーを正しい方向に切り替えられます:IOBUSDIRnはFDCの読み込み時のみロー(Z80→FDC方向)になり、FDCnチップセレクトは読み込みと書き込みの両方でアサートされます。 FDCペリフェラル制御
0xDC、0xDD、0xDEへの書き込みにより、PCB上のドライブ選択、ヘッドサイド、データ密度ラッチをクロックするシングルサイクルストローブ出力(DRIVEn、SIDEn、DDENn)が生成されます。FDCRESETn出力はZ80 RESET信号に直接接続されており、システムの電源投入またはハードウェアリセット時にWD1773が常にリセットされます。 MZ-700メモリ管理
MZ-700はI/Oポート0xE1〜0xE6への書き込みを使用して内部DRAMとCGROMを上位アドレス空間にバンク切り替えします。GALはデコードされたポートストローブでクロックされた登録済み出力を使用して2つの独立した状態ビットを追跡します:
- DISROM — 0xE3/0xE4への書き込みでセット、0xE1とRESETでクリア。セット時はホストがカードのROMウィンドウにDRAMをマップしたことを示します。
- INHROM — 0xE5への書き込みでセット、0xE6とRESETでクリア。セット時はDISROM状態に関わらずカードのROMを完全に抑制します。
INTEN登録済み出力はポート0xE7へのアクセスから生成されるINTCLKストローブでクロックされます。書き込みで有効が設定され(INTEN.DはWRnに従う)、読み込みでクリアされます。INTENはシステムのRESET入力で非同期リセットされます。INTCLK出力はPCB上の外部フリップフロップのクロック入力にフィードされます。
| ピン | 信号 | 方向 | 説明 |
|---|---|---|---|
| 1 | CLK | 入力 | 登録済み出力クロック |
| 2〜6, 8〜11 | A0〜A7 | 入力 | Z80 I/Oアドレスバス |
| 11 | IORQn | 入力 | Z80 I/Oリクエスト(アクティブロー) |
| 12 | WRn | 入力 | Z80書き込みストローブ(アクティブロー) |
| 13 | RDn | 入力 | Z80読み込みストローブ(アクティブロー) |
| 28 | RESET | 入力 | システムリセット(アクティブハイ) |
| 15 | DISROMSET | 出力 | ROM無効セットストローブ(アクティブロー) |
| 16 | DISROMCLR | 出力 | ROM無効クリアストローブ(アクティブロー) |
| 17 | INTCLK | 出力 | 割り込み有効フリップフロップクロック |
| 18 | INROMHSET | 出力 | ROM抑制セットストローブ(アクティブロー) |
| 19 | INTEN | 出力 | 割り込み有効登録済み出力(アクティブロー) |
| 20 | IOBUSDIRn | 出力 | バスバッファー方向 — ロー = Z80→FDC |
| 22 | INHROMCLR | 出力 | ROM抑制クリアストローブ |
| 23 | SIDEn | 出力 | ヘッドサイドセレクトストローブ(アクティブロー) |
| 24 | FDCRESETn | 出力 | WD1773リセット(アクティブロー、RESETに接続) |
| 25 | DDENn | 出力 | 倍密度有効ストローブ(アクティブロー) |
| 26 | DRIVEn | 出力 | ドライブセレクトストローブ(アクティブロー) |
| 27 | FDCn | 出力 | WD1773チップセレクト(アクティブロー) |
GAL16V8(
MREQnとRDnは上位アドレスライン(A12〜A15)と組み合わされて0xF000〜0xFFFFへのアクセスを検出します。ROMCSn出力は登録済み値であるため、アドレスバスの安定化によるチップセレクトのグリッチが抑制されます。セレクトはクロックエッジでのみ伝播します。 ROMアドレスマルチプレクシング
2つの追加出力がA9を超えるROMアドレスラインを駆動します:
SFD700_GAL2)はメモリ側のアドレスデコードを処理します。Z80が0xF000〜0xFFFFのファームウェアウィンドウをアドレスする際にROMチップセレクトを生成し、アドレスラインをROMに多重化して正しいファームウェアページを選択し、MZ-80AのDRQトリックを処理します。
ROMチップセレクトMREQnとRDnは上位アドレスライン(A12〜A15)と組み合わされて0xF000〜0xFFFFへのアクセスを検出します。ROMCSn出力は登録済み値であるため、アドレスバスの安定化によるチップセレクトのグリッチが抑制されます。セレクトはクロックエッジでのみ伝播します。 ROMアドレスマルチプレクシング
2つの追加出力がA9を超えるROMアドレスラインを駆動します:
- ROMA15 — MODESEL1ジャンパー入力から駆動され、ROMアドレス空間の上半分と下半分に格納された2つのファームウェアイメージ(MZ-700ページとMZ-80Aページ)を選択します。
- ROMA10 — 最も複雑な出力です。MZ-80Aターゲット(MODESEL1がロー)ではWD1773 DRQ信号と多重化されます:ROMが選択されてDRQがアサートされると、ROMA10は読み込みルーチンの1KB ミラーを選択し、DRQがアサートされていない場合は待機/再試行パスを含む別のミラーを選択します。これにより2MHz Z80がソフトウェアポーリングループなしでFDCデータ転送を処理できます。MZ-700ターゲット(MODESEL1がハイ)ではROMA10はアドレス修飾なしでDRQから直接駆動されます。
SFD700_2.PLD.MZ700— 簡略化されたROMA10ロジック:出力はDRQを直接追従します。SFD700_2.PLD.MZ80A— アドレス修飾付きの完全な多重化ROMA10と、開発中に使用されコメントアウトされた出力イネーブル制御。
| ピン | 信号 | 方向 | 説明 |
|---|---|---|---|
| 1 | CLK | 入力 | 登録済み出力クロック |
| 2〜7 | A10〜A15 | 入力 | Z80上位アドレスバス |
| 8 | MREQn | 入力 | Z80メモリリクエスト(アクティブロー) |
| 9 | RDn | 入力 | Z80読み込みストローブ(アクティブロー) |
| 12 | MODESEL0 | 入力 | モードジャンパービット0 |
| 13 | MODESEL1 | 入力 | モードジャンパービット1 — ROMページ/DRQロジックを選択 |
| 14 | ROMINH | 入力 | GAL1からのROM抑制状態 |
| 15 | ROMDIS | 入力 | GAL1からのROM無効状態 |
| 16 | DRQ | 入力 | WD1773データリクエスト |
| 17 | ROMA15 | 出力 | ROMアドレスビット15(ファームウェアページ選択) |
| 18 | ROMA10 | 出力 | ROMアドレスビット10(MZ-80AのDRQマルチプレクサー) |
| 19 | ROMCSn | 出力 | ROMチップセレクト(アクティブロー、登録済み) |
PLDソースファイルはLogical Devices CUPL v4.0(コンパイラー出力ヘッダーではCUPL 5.0aとも呼ばれる)DOS時代のツールチェーンでコンパイルされます。このバージョンが必要な理由は、Windows時代の後継であるWinCUPLがAtmel互換GALデバイスのみをターゲットとし、Lattice GAL26CV12をサポートしていないためです。CUPL v4.0バイナリはDOSBoxまたは類似のDOSエミュレーターで現代のホスト上で実行できます。あるいは
CUPL/ディレクトリの事前コンパイル済みJEDECファイルを再コンパイルなしで直接使用できます。
ソースから再コンパイルするには、CUPL/ディレクトリに含まれているバッチスクリプトを使用します:
# GAL1のコンパイル(GAL26CV12)— CUPLディレクトリ内で実行 cupl -j -f -a g26cv12 SFD700_1 # GAL2のコンパイル(GAL16V8) cupl -j -f -a g16v8 SFD700_2
-jフラグはJEDEC出力(.JED)を生成し、-fはヒューズプロット(.DOC)を生成し、-a <デバイス>はターゲットデバイスを指定します。コンパイル済み出力は同じディレクトリに書き込まれます:
SFD700_1.JED— GAL1用JEDECヒューズファイル、プログラム準備完了。SFD700_2.JED— GAL2用JEDECヒューズファイル、プログラム準備完了。SFD700_1.DOC/SFD700_2.DOC— 検証用の人間可読なヒューズプロットとチップ図。SFD700_1.ABS/SFD700_2.ABS— 一部のプログラマーユーティリティが使用するバイナリ中間ファイル。
GAL16V8(GAL2)
GAL16V8は事実上すべての現代デバイスプログラマーでネイティブサポートされています。TL-866 II+またはオープンソースの
GAL16V8は事実上すべての現代デバイスプログラマーでネイティブサポートされています。TL-866 II+またはオープンソースの
miniproユーティリティを使用する場合:
minipro -p GAL16V8 -w SFD700_2.JED
Minipro形式のJED(
SFD700_G.JED)もCUPL/ディレクトリに直接使用できるよう提供されています。プログラミング後は以下で検証します:
minipro -p GAL16V8 -v SFD700_2.JED
GAL26CV12(GAL1)
GAL26CV12は28ピンPLCC/DIPデバイスで、標準のTL-866 II+デバイスデータベースにリストされていません。プログラミングにはPLCC-28からDIP-28へのアダプターとMinipro
GAL26CV12は28ピンPLCC/DIPデバイスで、標準のTL-866 II+デバイスデータベースにリストされていません。プログラミングにはPLCC-28からDIP-28へのアダプターとMinipro
infoic.xmlデータベースのカスタムデバイスエントリーが必要です。事前設定済みのinfoic.xmlがCUPL/ディレクトリに含まれています。アダプターを装着してカスタムデータベースを配置した状態で:
minipro -p GAL26CV12 -w SFD700_1.JED
旧式の専用GALプログラマー(例:BP Microsystems、Data I/O)を使用する場合は、標準JEDECの
.JEDファイルを直接使用します。すべてのJEDEC準拠GALプログラマーはCUPLが生成するJEDEC 3C形式を受け入れます。
両方のGALデバイスはプログラムされた設定をEEPROMに保持し、ロード遅延なしに電源投入直後から使用できます。JTAGテストポイントが提供されている場合はインサーキットで消去・再プログラムでき、ベンチプログラミングのためにソケットから取り外すこともできます。
CPLD
デバイス
SFD-700 v1.2のCPLDは84ピンPLCKパッケージのAltera MAX7000S EPM7128SLC84-15です。最大伝播遅延15nsで5V耐性EEPROMベースのCPLDで、JTAGによるインシステムプログラマビリティを備えています。ビルド成功後のリソース使用率は以下の通りです:
| リソース | 使用 | 利用可能 | 使用率 |
|---|---|---|---|
| マクロセル | 72 | 128 | 56% |
| レジスター | 37 | 128 | 29% |
| I/Oピン | 65 | 68 | 96% |
| プロダクト項 | 179 | — | — |
| グローバルクロック | 2 | 2 | 100% |
72個のマクロセルは8つの機能ブロックに分割されています。2つの信号が専用グローバルルーティングリソースに割り当てられています:
オンボードの16MHzクリスタル発振器が
純粋な組み合わせ論理がZ80 I/Oサイクル(IORQnとRDnまたはWRnのアサート)を3つのアドレスブロックにわたってデコードします:0xD8〜0xDBのWD1773 FDCレジスター、0xDC〜0xDFのFDC制御レジスター、0x60〜0x63のページングおよびモードレジスター。MZ-700およびMZ-1500ターゲット(MODE 1と4)では、デコーダーはI/Oポート0xE0〜0xE6への書き込みもキャプチャしてホストメモリ管理状態を追跡します。設計の最大ファンアウトノードはアドレスデコードツリーに起因し、67個のマクロセル入力を駆動します。 メモリアドレスデコーダー
Z80メモリサイクル(MREQnとRDnまたはWRn)をデコードして、オンボードフラッシュROM(
I/Oポート0xDCへの書き込みにより、4つのアクティブローのドライブセレクト出力(DRVSAn〜DRVSDn)とモーター有効ライン(MOTOR)を駆動する8ビットの登録済み値がロードされます。ビット[2:0]が選択ドライブをエンコードします(値4〜7がドライブA〜Dを選択、0はすべて非選択)。ビット7がスピンドルモーターを制御します。ヘッドサイド選択(0xDD)と倍密度モード(0xDE)は別々のシングルビットレジスターで管理されます。 データバス反転とマルチプレクシング
WD1773はビット単位の反転データを必要とします。CPLDは専用の8ビット反転データバス(
WD1773のINTRQ出力は単一の登録済み有効ビットでゲートされています。I/Oポート0xDFへの書き込みはINTRQのZ80 INT ラインへのルーティングを有効化し、0xDFからの読み込みで有効を無効化します。セカンダリ出力Z80_EXWAITnは、ホストタイミングで必要な場合にFDCレジスターアクセス中に外部ウェイトステートを挿入するために使用できます。 MZ-700 / MZ-1500メモリ管理
MZ-700とMZ-1500は0xE0〜0xE6へのI/O書き込みを使用して内部DRAMとROMを上位アドレス空間にバンク切り替えします。CPLDはこれらの書き込みを監視して2ビットの状態レジスターを維持します:0xE5への書き込みでページレジスターの内容に関わらず
3つのモードジャンパー入力(MODE[2:0])はZ80_RESETnの立ち上がりエッジでサンプリングされ、登録済み値にラッチされます。I/Oポート0x63を読み込むとこの値が返され、ブートファームウェアがDIPスイッチや手動設定なしにホストマシンを自動検出できます。
ピン割り当て
CLK_16M(プライマリクロック)とZ80_RESETn(同期リセット)で、デバイス全体のクロックとリセットスキューを最小化します。
クロック生成オンボードの16MHzクリスタル発振器が
CLK_16Mグローバルクロック入力を駆動します。単一の登録済みトグルマクロセルがこれを2分周してCLK_FDC(WD1773 FDCチップクロック入力に直接供給される8MHzクロック)を生成します。
I/Oアドレスデコーダー純粋な組み合わせ論理がZ80 I/Oサイクル(IORQnとRDnまたはWRnのアサート)を3つのアドレスブロックにわたってデコードします:0xD8〜0xDBのWD1773 FDCレジスター、0xDC〜0xDFのFDC制御レジスター、0x60〜0x63のページングおよびモードレジスター。MZ-700およびMZ-1500ターゲット(MODE 1と4)では、デコーダーはI/Oポート0xE0〜0xE6への書き込みもキャプチャしてホストメモリ管理状態を追跡します。設計の最大ファンアウトノードはアドレスデコードツリーに起因し、67個のマクロセル入力を駆動します。 メモリアドレスデコーダー
Z80メモリサイクル(MREQnとRDnまたはWRn)をデコードして、オンボードフラッシュROM(
ROM_CSn)と静的RAM(RAM_CSn)のアクティブローチップセレクト出力を生成します。2つの独立した8ビットページレジスター — EXXX_PAGE(0x60経由でロード)とFXXX_PAGE(0x61経由でロード)— のビット[6:0]がアドレスビットROM_A10とRAM_A10に駆動され、最大512KBのアドレス指定可能なストレージ内の4KBウィンドウをバンク切り替えします。ビット7(D7)はウィンドウごとにFlash ROMまたはSRAMを独立して選択します。
ドライブとモーター制御I/Oポート0xDCへの書き込みにより、4つのアクティブローのドライブセレクト出力(DRVSAn〜DRVSDn)とモーター有効ライン(MOTOR)を駆動する8ビットの登録済み値がロードされます。ビット[2:0]が選択ドライブをエンコードします(値4〜7がドライブA〜Dを選択、0はすべて非選択)。ビット7がスピンドルモーターを制御します。ヘッドサイド選択(0xDD)と倍密度モード(0xDE)は別々のシングルビットレジスターで管理されます。 データバス反転とマルチプレクシング
WD1773はビット単位の反転データを必要とします。CPLDは専用の8ビット反転データバス(
ID[7:0])に接続し、読み込みと書き込みの両方向で極性反転を透過的に処理します。Z80がFDCレジスターを読み込む際、反転バスはZ80データバスに再反転されます。FDCレジスターへの書き込み時はZ80データバスがID[7:0]に反転されます。ホストがページレジスターを読み返す場合、CPLDは格納されたページ値を直接Z80データバスに駆動します。
MZ-80AおよびMZ-1200ターゲット(MODE 0)ではWD1773 DRQ信号がフラッシュROMアドレスビットA10(ROM_A10)に多重化されます。ブートROMの各1KBセグメントには読み込みルーチンのミラーコピーが含まれており、DRQ状態が正しいコピーを直接選択することで、2MHz Z80がFDCデータレートを確実に処理するのに十分な速度でソフトウェアポーリングループを実行できないという問題を回避します。
割り込み制御WD1773のINTRQ出力は単一の登録済み有効ビットでゲートされています。I/Oポート0xDFへの書き込みはINTRQのZ80 INT ラインへのルーティングを有効化し、0xDFからの読み込みで有効を無効化します。セカンダリ出力Z80_EXWAITnは、ホストタイミングで必要な場合にFDCレジスターアクセス中に外部ウェイトステートを挿入するために使用できます。 MZ-700 / MZ-1500メモリ管理
MZ-700とMZ-1500は0xE0〜0xE6へのI/O書き込みを使用して内部DRAMとROMを上位アドレス空間にバンク切り替えします。CPLDはこれらの書き込みを監視して2ビットの状態レジスターを維持します:0xE5への書き込みでページレジスターの内容に関わらず
ROM_CSnとRAM_CSnを抑制する抑制状態を設定し、0xE3、0xE4、または0xE6への書き込みで抑制をクリアして拡張カードウィンドウを再有効化します。
モードレジスター3つのモードジャンパー入力(MODE[2:0])はZ80_RESETnの立ち上がりエッジでサンプリングされ、登録済み値にラッチされます。I/Oポート0x63を読み込むとこの値が返され、ブートファームウェアがDIPスイッチや手動設定なしにホストマシンを自動検出できます。
EPM7128SLC84-15(84ピンPLCC)の主要なピン割り当て。すべてのI/Oは3.3V LVTTL;MAX7000Sファミリーは5V入力耐性があり、5V Sharp MZバスと直接互換です。
| 信号 | ピン | 方向 | 説明 |
|---|---|---|---|
| CLK_16M | 83 | 入力 | 16MHzクリスタル発振器 — グローバルクロック |
| CLK_FDC | 81 | 出力 | WD1773への8MHzクロック |
| CLK_BUS0 | 2 | 入力 | ホストZ80バスクロック |
| Z80_RESETn | — | 入力 | アクティブローリセット — グローバルリソース、MODEをラッチ |
| A[15:0] | 4〜25 | 入力 | Z80アドレスバス |
| D[7:0] | 27〜35 | 双方向 | Z80データバス |
| ID[7:0] | 64〜74 | 双方向 | 反転データバス(WD1773側) |
| M1n | 36 | 入力 | Z80 M1マシンサイクルインジケーター |
| RDn | 37 | 入力 | Z80読み込みストローブ |
| WRn | 39 | 入力 | Z80書き込みストローブ |
| IORQn | 40 | 入力 | Z80 I/Oリクエスト |
| MREQn | 41 | 入力 | Z80メモリリクエスト |
| Z80_INT | 44 | 出力 | Z80への割り込み出力(ゲートされたINTRQ) |
| Z80_EXWAITn | 45 | 出力 | Z80への外部ウェイトリクエスト |
| FDCn | 63 | 出力 | WD1773チップセレクト(アクティブロー) |
| INTRQ | 61 | 入力 | WD1773割り込みリクエスト |
| DRQ | 60 | 入力 | WD1773データリクエスト |
| DDENn | 58 | 出力 | WD1773への倍密度有効(アクティブロー) |
| SIDE1 | 57 | 出力 | ヘッドサイド選択 |
| MOTOR | 56 | 出力 | スピンドルモーター有効 |
| DRVSAn | 55 | 出力 | ドライブA選択(アクティブロー) |
| DRVSBn | 54 | 出力 | ドライブB選択(アクティブロー) |
| DRVSCn | 52 | 出力 | ドライブC選択(アクティブロー) |
| DRVSDn | 51 | 出力 | ドライブD選択(アクティブロー) |
| ROM_CSn | 77 | 出力 | フラッシュROMチップセレクト(アクティブロー) |
| RAM_CSn | 76 | 出力 | 静的RAMチップセレクト(アクティブロー) |
| ROM_A10 | 80 | 出力 | ROMページアドレスビット / DRQマルチプレクサー(MZ-80A MODE) |
| RAM_A10 | 79 | 出力 | RAMページアドレスビット |
| MODE[2:0] | 49,48,50 | 入力 | ホストマシンモードジャンパー |
CPLDビットストリームはQuartus II 13.0.1 SP1 Web Editionを使用してコンパイルします。13.x以降のQuartusリリースがMAX7000Sデバイスファミリーのサポートを削除したため、このバージョンが必要です。Web EditionはIntel FPGA Software Archiveから無料で入手できます。
リポジトリをクローンしてプロジェクトを開きます:
git clone https://git.eaw.app/eaw/SFD700 cd SFD700/CPLD/v1.2/build
コマンドラインからコンパイルするには:
quartus_map --read_settings_files=on sfd700 # 解析と合成 quartus_fit --read_settings_files=on sfd700 # フィッター(配置配線) quartus_asm --read_settings_files=on sfd700 # アセンブラー — sfd700.pofを生成 quartus_sta sfd700 # タイミング解析(オプション)
あるいはQuartus II GUIで
CPLD/v1.2/build/sfd700.qpfを開き、Processing → Start Compilationを使用します。ビルドが成功すると出力プログラミングファイルが以下に書き込まれます:
CPLD/v1.2/build/output_files/sfd700.pof
期待されるリソース使用率:72/128マクロセル(56%)、65/68ピン(96%)、37レジスター。大幅な偏差は合成設定の不一致を示しています。QuartusプロジェクトのデバイスがMAX7000Sファミリーの
CPLDのプログラミング
EPM7128SLC84-15に設定されていることを確認してください。
EPM7128SLC84-15は4ピンJTAGポート(TDI、TDO、TMS、TCK)を介してAltera USB-Blasterまたは互換クローンを使用してプログラムします。USB-BlasterをSFD-700 PCBの10ピンJTAGヘッダーとプログラミングホストのUSBポートに接続します。
コマンドラインからプログラムするには:
quartus_pgm -c "USB-Blaster" -m JTAG \ -o "p;CPLD/v1.2/build/output_files/sfd700.pof"
またはQuartus II Programmer GUIを使用します:
- Tools → Programmerを開きます。
- Hardware SetupをクリックしてUSB-Blasterを選択します。
- Add Fileをクリックして
output_files/sfd700.pofを選択します。 - Program/Configureにチェックを入れ、オプションでVerifyにもチェックを入れます。
- Startをクリックします。プログラミングは数秒で完了します。
I/Oレジスターマップ
CPLDはZ80 I/Oアドレスバスをデコードして以下のレジスターセットを実装します。WD1773は反転データを使用しますが、CPLDが反転を透過的に処理します。
| ポート | R/W | 説明 |
|---|---|---|
| 0xD8〜0xDB | R/W | WD1773 FDCレジスター(ステータス、コマンド、トラック、セクター、データ)。 |
| 0xDC | W | ドライブ&モーター:ビット[2:0]はドライブを選択(4=A、5=B、6=C、7=D、0=なし);ビット[7]はモーターを制御。 |
| 0xDD | W | ヘッドサイド:D0=0 → サイド1、D0=1 → サイド0。 |
| 0xDE | W | データレート:D0=0 → 倍密度、D0=1 → 単密度。 |
| 0xDF | W/R | 割り込み:書き込み → WD1773 INTをホストに有効化;読み込み → WD1773 INTを無効化。 |
| 0x60 | R/W | EXXXページレジスター:D7はストレージ選択(0=Flash ROM、1=RAM);ビット[6:0]はE300:EFFFにマップされた4KBページを選択。 |
| 0x61 | R/W | FXXXページレジスター:D7はストレージ選択(0=Flash ROM、1=RAM);ビット[6:0]はF000:FFFFにマップされた4KBページを選択。 |
| 0x63 | R | モードレジスター:MODEジャンパー値(0〜6)を読み返す。 |
| 0xE1 | W | MZ-700/MZ-1500のみ:オンボードROMを無効化(ホストがDRAMをD000:FFFFにマップ)。 |
| 0xE3, 0xE4 | W | MZ-700/MZ-1500のみ:オンボードROMを再有効化。 |
| 0xE5 | W | MZ-700/MZ-1500のみ:すべてのオンボードROM/RAMアクセスを抑制。 |
| 0xE6 | W | MZ-700/MZ-1500のみ:ROM抑制をクリア、オンボードROM/RAMを再有効化。 |
メモリマップ
CPLDはオンボードフラッシュROMと静的RAMを上位アドレス空間の2つのページドウィンドウを通じてホストに提供します。各ウィンドウは4KBで、その物理ページはI/Oポート0x60と0x61で独立して設定でき、最大128×4KB = 512KBのアドレス可能なフラッシュまたはRAMストレージが可能です。
| ウィンドウ | アドレス範囲 | ページレジスター | 注意事項 |
|---|---|---|---|
| EXXX | E300:EFFF | 0x60 | E000:E2FFはMZ-700/MZ-1500のメモリマップドI/O用に予約されているため、4KBページのうちファームウェア(RFS)が使用できるのは3.75KBのみ。 |
| FXXX | F000:FFFF | 0x61 | 完全な4KBウィンドウ。デフォルトページ0にMZ-80A AFI ROM、デフォルトページ1にMZ-700 AFI ROMが格納。 |
MZ-80AとMZ-1200ではCPLDがWD1773 DRQ信号をフラッシュROMアドレスラインA10にルーティングします。アドレスラインの両側にDRQがアサートされた際の短いパスを持つ読み込みルーチンのミラーコピーが格納されています。これによりソフトウェアポーリングが不要になり、2MHzでの確実なデータ転送が可能になります。
PCB
v1.1 PCB
PCBはCPLD、ROM/RAMストレージ、追加サポート回路(初期v1.0/v1.1リビジョンはCPLDの代わりに2つのGALデバイスを使用)が必要なため、SFD-800よりも複雑です。

v1.2 PCB

マニュアル
SFD-700 mkIIの詳細なドキュメントは3つの別々のマニュアルで提供されています:
| マニュアル | 説明 |
|---|---|
| ユーザーマニュアル | ボード概要、MODEジャンパー設定、ドライブ取り付け、ROMファイリングシステムの使い方、トラブルシューティング |
| テクニカルガイド | ハードウェアアーキテクチャ、CPLD設計、I/Oレジスターマップ、メモリマップ、ビルド/プログラミング手順 |
| デベロッパーズガイド | VHDLソースコードの詳細な説明(非VHDLプログラマー向けの解説付き)、プロセスごとの分析、CPLD改造ガイド |
ドキュメント
上記リンクからオリジナルのK&P SFD-800ユーザーマニュアルをダウンロードできます。この設計に関連しています。ドイツ語で書かれているため、非ドイツ語話者の場合はスマートフォンのGoogle翻訳アプリのリアルタイムカメラ翻訳(ドイツ語→<お使いの言語>)での翻訳をお勧めします。
ファイル
すべてのプロジェクトファイルはGiteaでご覧ください。
v1.2 PCB GerberファイルはGitHubリポジトリのreleases/ディレクトリに提供されています。v1.2ボードが6枚余っています — 興味のある方はウェブサイトからご連絡ください(送料のみ)。
クレジット
オリジナルのSFD-700設計はドイツのアーヘンにあるKersten & Partners GmbH(1985年著作権)のもので、同社は現在は廃業しています。最後に判明している住所に複製の許可を求めて連絡を試みましたが、返答は得られませんでした。
SFD-700 mkIIはオリジナルのコンセプトに着想を得た新しい設計です。PCBレイアウト、回路図、プログラマブルロジック(v1.0/v1.1のCUPL;v1.2のVHDL)はゼロから書かれています。K&P製品には存在しないホストモードロジック、ROM/RAMページング、MZ-80AのDRQをアドレスラインに変換する機能が独自に追加されています。
SFD-700 mkIIはオリジナルのコンセプトに着想を得た新しい設計です。PCBレイアウト、回路図、プログラマブルロジック(v1.0/v1.1のCUPL;v1.2のVHDL)はゼロから書かれています。K&P製品には存在しないホストモードロジック、ROM/RAMページング、MZ-80AのDRQをアドレスラインに変換する機能が独自に追加されています。
ライセンス
このデザイン(ハードウェアおよびソフトウェア)はGNU Public Licence v3のもとでライセンスされています。
GNU Public License v3
このプロジェクトでGPL v3とマークされたソースファイルおよびバイナリファイルはフリーソフトウェアです。フリーソフトウェア財団が発行するGNU一般公衆ライセンスのバージョン3、またはそれ以降のバージョンの条件のもとで、再配布および改変することができます。
ソースファイルは有用であることを願って配布されていますが、いかなる保証もありません。商品性や特定目的への適合性の黙示的な保証も含みません。詳細についてはGNU一般公衆ライセンスをご参照ください。
このプログラムとともにGNU一般公衆ライセンスのコピーを受け取っているはずです。受け取っていない場合はhttp://www.gnu.org/licenses/をご覧ください。
ソースファイルは有用であることを願って配布されていますが、いかなる保証もありません。商品性や特定目的への適合性の黙示的な保証も含みません。詳細についてはGNU一般公衆ライセンスをご参照ください。
このプログラムとともにGNU一般公衆ライセンスのコピーを受け取っているはずです。受け取っていない場合はhttp://www.gnu.org/licenses/をご覧ください。