シリアルEEPROMでCP/M [Z80]
SDカードは使用制限があるので自作基板で使用した場合、公開し辛い面がありました。SDカードの中でも使用されているであろうEEPROMを使って CP/M を起動できないか実験しました。
秋月さんで販売している1MbitのシリアルEEPROM(S-24CM01CIーJ8T1U4)を購入していましたが、今回はより容量が大きな海外の通販で見つけた 32MBit EEPROM(W25Q32JVSIQ) を使って実験してみました。後者の方が書込み速度が遅く、許容している書込み回数も少ないのですが容量の大きさを優先しました。
最近、秋月さんで 4Mbit のフラッシュメモリ(IS25LP040E) を販売開始したようです。
今回使用した 32MBit EEPROM(W25Q32JV) のブロック図が下図になります。消去時の単位は 4KBytes/32KByte/64KByte/chiperase と柔軟性があり、最小単位は 4KByte です。
EEPROM とのインターフェースは基本的には SPI で今回は GAL を使って Z80 側のソフトウェアで対応することにしました。この EEPROM はデータ線が 2bit や 4bit の拡張インターフェースの機能もあるのでソフト対応しておくことで後日高速化できる余地を残すという意図もあります。
まずはデータ線が 1bit の SPI インターフェースでの接続実験を行いました。
下図は今回の EEPROM 評価時の回路です。上述のように GAL(GAL22V10D)を使用して EEPROM を接続しています。
実験環境は下図のように Z80GalCompact の CPU ソケットを拡張して EEPROM を実装しています。
下図はデバイスの ID を読込んだ際のロジアナ波形です。ソフト対応での転送ビットレートは送信/受信でそれぞれ 770KB/590KB 程です。Z80GalCompact は Z80 が 20MHz で動作していますが、シリアル通信用のタイマー割込みのため実質速度は 16MHz 程度です。
下図はステータス1~3の書込み後に読み出した際のロジアナ波形です。今回使用した EEPROM は型名の最後の Special Optoins が'Q'で Status2 の QE bit が 1 に固定になっています。
下図はデータリード時の波形で先頭の 0x03 がリードコマンドで次の 3 バイトがリード対象のアドレスでその後にリードデータが続きます。複数個所でクロックに隙間が発生しているのはシリアル通信のためのタイマー割込みのためです(この波形はCP/M起動時のもので割込み許可状態で動作している)。
リードデータ長に関しては自由にリードできるのですが、ライトの場合は、事前にデータを消去する必要があり、消去の最小単位が前述したように4Kバイトなので CP/M で使う場合のブロック長は最小でも4Kバイトということになります。
CP/M で使用する場合のブロック長は前述のように消去の最小単位である4Kバイトにし、ディスクパラメータを新規に作成し、ブロッキング/デブロッキング処理を実装しました。
下図は CP/M を立ち上げて STAT コマンドで DSK: のパラメータを表示した際の画面キャプチャーです。モニタで CP/M の HEX ファイルをロード後、GO コマンドで起動していますが、 シリアル送受信の割込みルーチンをBIOS 内の処理へ切替えている関係でスタートメッセージの先頭が文字化けしていますね。4KB のバッファを BIOS 内に持っているため 59K CP/M です。
アクセス速度に関しては SD カード時との差異を殆ど感じずに違和感の無い速度でした(消去に時間が掛かるので大量書込み時は遅く感じるかもしれません)。
冒頭で書いたように SD カードを利用して開発した CP/M 基板を公開し辛かったのですが、今回シリアル EEPROM で CP/M を起動できたので色々応用できそうです。
★追記 2023/06/06 {
HITECH-C で hello.c をコンパイルするのに要する時間を比較してみました。下の画面キャプチャで前半がSDカードでブートした従来の CP/M で後半が EEPROM でブートした CP/M です。コンパイル時間を TeraTerm のマクロで計測した結果が "Start=" と書かれた行になります。特にリンク時間(=書込み量が多い)が遅い感じで EEPROM の場合、1.75倍程度の時間が掛かっています。
}
Twitterに投稿した動画付きメッセージも貼っておきます。
秋月さんで販売している1MbitのシリアルEEPROM(S-24CM01CIーJ8T1U4)を購入していましたが、今回はより容量が大きな海外の通販で見つけた 32MBit EEPROM(W25Q32JVSIQ) を使って実験してみました。後者の方が書込み速度が遅く、許容している書込み回数も少ないのですが容量の大きさを優先しました。
最近、秋月さんで 4Mbit のフラッシュメモリ(IS25LP040E) を販売開始したようです。
今回使用した 32MBit EEPROM(W25Q32JV) のブロック図が下図になります。消去時の単位は 4KBytes/32KByte/64KByte/chiperase と柔軟性があり、最小単位は 4KByte です。
EEPROM(W25Q32JV)のブロック図 |
|
EEPROM とのインターフェースは基本的には SPI で今回は GAL を使って Z80 側のソフトウェアで対応することにしました。この EEPROM はデータ線が 2bit や 4bit の拡張インターフェースの機能もあるのでソフト対応しておくことで後日高速化できる余地を残すという意図もあります。
まずはデータ線が 1bit の SPI インターフェースでの接続実験を行いました。
下図は今回の EEPROM 評価時の回路です。上述のように GAL(GAL22V10D)を使用して EEPROM を接続しています。
EEPROM 評価用回路図 |
|
実験環境は下図のように Z80GalCompact の CPU ソケットを拡張して EEPROM を実装しています。
Z80GalCompact に接続した EEPROM 基板 |
|
EEPROM 部のZOOM |
|
下図はデバイスの ID を読込んだ際のロジアナ波形です。ソフト対応での転送ビットレートは送信/受信でそれぞれ 770KB/590KB 程です。Z80GalCompact は Z80 が 20MHz で動作していますが、シリアル通信用のタイマー割込みのため実質速度は 16MHz 程度です。
デバイスID読込み時のロジアナ波形例 |
|
下図はステータス1~3の書込み後に読み出した際のロジアナ波形です。今回使用した EEPROM は型名の最後の Special Optoins が'Q'で Status2 の QE bit が 1 に固定になっています。
ステータスリード/ライト時のロジアナ波形例 |
|
下図はデータリード時の波形で先頭の 0x03 がリードコマンドで次の 3 バイトがリード対象のアドレスでその後にリードデータが続きます。複数個所でクロックに隙間が発生しているのはシリアル通信のためのタイマー割込みのためです(この波形はCP/M起動時のもので割込み許可状態で動作している)。
リードデータ長に関しては自由にリードできるのですが、ライトの場合は、事前にデータを消去する必要があり、消去の最小単位が前述したように4Kバイトなので CP/M で使う場合のブロック長は最小でも4Kバイトということになります。
シリアルEEPROMリード時のロジアナ波形例 |
|
CP/M で使用する場合のブロック長は前述のように消去の最小単位である4Kバイトにし、ディスクパラメータを新規に作成し、ブロッキング/デブロッキング処理を実装しました。
下図は CP/M を立ち上げて STAT コマンドで DSK: のパラメータを表示した際の画面キャプチャーです。モニタで CP/M の HEX ファイルをロード後、GO コマンドで起動していますが、 シリアル送受信の割込みルーチンをBIOS 内の処理へ切替えている関係でスタートメッセージの先頭が文字化けしていますね。4KB のバッファを BIOS 内に持っているため 59K CP/M です。
アクセス速度に関しては SD カード時との差異を殆ど感じずに違和感の無い速度でした(消去に時間が掛かるので大量書込み時は遅く感じるかもしれません)。
DSK:パラメータ表示画面例 |
|
冒頭で書いたように SD カードを利用して開発した CP/M 基板を公開し辛かったのですが、今回シリアル EEPROM で CP/M を起動できたので色々応用できそうです。
★追記 2023/06/06 {
HITECH-C で hello.c をコンパイルするのに要する時間を比較してみました。下の画面キャプチャで前半がSDカードでブートした従来の CP/M で後半が EEPROM でブートした CP/M です。コンパイル時間を TeraTerm のマクロで計測した結果が "Start=" と書かれた行になります。特にリンク時間(=書込み量が多い)が遅い感じで EEPROM の場合、1.75倍程度の時間が掛かっています。
HITECH-Cでのhello.cコンパイル時間比較 |
|
★追記 2023/06/13 {
今回使用している EEPROM は読出しに関しては任意のアドレスから任意長のリードができるので EEPROM バッファにヒットしない場合には EEPROM からデータを読込んで DMA 領域に直に書き込むようにしました。このようにブロッキング/デブロッキング処理をハイブリッド化することで読込み時のバッファリング処理を極力省き高速化しました。
この変更後の HITECH-C で hello.c をコンパイルするのに要した時間を測定した結果が下図になります。前半が SD ブートで後半が EEPROM ブートになります。なんと SD カード上でのコンパイルより高速になりました^^
}
今回使用している EEPROM は読出しに関しては任意のアドレスから任意長のリードができるので EEPROM バッファにヒットしない場合には EEPROM からデータを読込んで DMA 領域に直に書き込むようにしました。このようにブロッキング/デブロッキング処理をハイブリッド化することで読込み時のバッファリング処理を極力省き高速化しました。
この変更後の HITECH-C で hello.c をコンパイルするのに要した時間を測定した結果が下図になります。前半が SD ブートで後半が EEPROM ブートになります。なんと SD カード上でのコンパイルより高速になりました^^
EEPROM上でのhello.cコンパイル時間(改善版) |
|
Twitterに投稿した動画付きメッセージも貼っておきます。
32MbitのシリアルEEPROM(W25Q32JVS)を使ってCP/Mを起動できました
— skyriver (@wcinp) June 4, 2023
体感的にはアクセスがSDカードより遅いという感じはありませんでした
消去の最小単位が4Kバイトなのでディスクパラメータを新設しブロッキング/デブロッキング処理を実装しています#Z80GalCompact #CPMhttps://t.co/eYbvvMhUSV pic.twitter.com/N11V0VYHYD
コメント 0