CP/M v2.23

概要

現在の主流オペレーティングシステムはマイクロコンピューターでは Linux と Windows ですが、かつてはすべて Digital Research が CP/M(Control Program/Monitor)を作成したことから始まりました。CP/M はマイクロコンピューター向けの最初の本格的なオペレーティングシステムの一つで、様々なハードウェアをまたいでアプリケーションを実行するための共通手段を提供しました。CP/M が動作するマシンは何千ものプログラムにアクセスでき、こうして Sharp MZ80A に CP/M を動かすという探求が始まりました。

Sharp MZ80A 向けの CP/M バージョンは Micro Technology によって作成されましたが、80 桁スクリーンがないため、アップグレードなしではあまり役に立ちませんでした。調査したところ、Kuma などのサードパーティが 80 桁アップグレードを開発し、後に SUC から入手できるようになりましたが、MZ80A の CP/M は、多くの記事で言及されているものの、2020 年時点で実際に入手するのは非常に困難でした。original.sharpmz.org などの優れたサイトは 80K/80B/800 バージョンを提供していますが、MZ80A 向けは提供していません。

80 桁カラーアップグレードボードと Rom Filing System を開発した主な目的は、MZ80A で CP/M を実現することでした。FPGA ベースのハードウェアエミュレータープロジェクトでは様々な桁数の出力、カラー、グラフィックスに対応する変更を簡単に追加できますが、ヴィンテージマシンへの変更を最小限に抑えた実際のオリジナルハードウェアで行うことは、より大きな挑戦であり、1983 年にこのマシンを初めて手にして以来の個人的な願望でもありました。過去のアップグレードのほとんどはオリジナル PCB へのカットやリンクが必要ですが、私は特にそれをしたくありませんでした。Sharp が作ったままのオリジナルハードウェアを保ちたいのです!オリジナル PCB への私の唯一の変更は、チップ(IC8 74LS165 ビデオシフトレジスター)をソケット化することで、これは使用中に故障して交換が必要になった場合でも簡単に行え、マシンは 100% オリジナルの状態に保たれ、元の工場出荷状態に簡単に戻せます。

こうして CP/M を動作させようとしましたが、ネット上に大量の情報があっても簡単な作業ではありませんでした。まず、MZ80A 向けの Micro Technology 版 CP/M の入手が非常に困難だったため、MZ80K と MZ80B バージョンに頼ることにしました。次に、MZ80A が反転データを読み取るように設計されているという問題も加わり、様々な風変わりなディスクフォーマットの問題に直面しました。長い話を短くすると、独自の ROM ベース版 CBIOS を作成し、CP/M v2.23 の BDOS+CCP と組み合わせることにしました。このセクションではその作業の詳細を説明します。

CP/M ブートプロセス

CP/M の起動は 2 つのフェーズで行われます:

  1. オリジナルの AFI フロッピーディスク制御ソフトウェアを使用して反転ブートセクターを読み込み、0x0000 に制御コード 0x02 + “IPLPRO” が含まれていることを確認し、カプセル化されたブートローダーに制御を渡す
  2. 0x9C00 から始まる CCP、BDOS、CBIOS を読み込む。CBIOS が制御を引き継ぎ、異なるディスクフォーマットを適用して異なる FDC コントローラーロジックを使用する(つまりデータを再反転する)。
このため、MZ80A AFI ROM(リポジトリで入手可能)を逆アセンブルして、何をしているかを理解しました。最初の読み込みでは、ディスクが MZ80A でブート可能かどうかを確認します。MZ80K では、ブート可能ディスクのマーカー(フォーマットが大きく異なりデータを反転しないという点以外に)は最初のセクターの先頭バイトに 01 + IPLPRO でした。MZ80B では 03 + IPLPRO でした。

MZ80A 版の CP/M を持っていなかったため、MZ80K バージョンを読み込もうとしましたが、非反転データのため MZ80K ブートディスクを MZ80A フォーマットに変換する必要がありました。変換後に CP/M を起動しようとしましたが、ディスクコントローラーなどの非互換性がありました!その後 Micro Technologies の CP/M の MZ80B と MZ800 バージョンを調べましたが、これらも異なるディスクフォーマットを使用しており、最終的にはカスタム CP/M を構築して独自の CBIOS を作成するのが最善のアプローチだと判断しました。


更新 — MZ-80K ディスクの直接サポート:RFS CP/M ブートローダーと CBIOS は、オリジナルの MZ-80K ディスクフォーマットを直接自動検出するようになったため、MZ-80K ディスクを MZ-80A フォーマットに変換する必要がなくなりました。MZ80AFI カード経由でブートする際、コントローラーはディスク上のセクターサイズ(MZ-80K ディスクは 128 バイト、MZ-80A ディスクは 256 バイト)を報告します。01h + IPLPRO マーカーを持つ 128 バイトの非反転ディスクは MZ-80K CP/M ディスクとして認識され、予約されたシステムトラックが順に読み込まれ、カプセル化されたブートローダー(JP 09803H)に制御が渡されます。起動後、オリジナルの MZ-80K CP/M ディスクは SD カードドライブや ROM ドライブと並んで、CP/M ドライブ C: および D: として読み取り用に直接マウントされます。これは MZ80AFI カードを装着した実機の MZ-80A、および MZ80AFI インターフェースを備えた MZ-80A または新しい MZ-80K ペルソナで動作する picoZ80 のいずれでも機能します。

CBIOS

CP/M は 3 つの独立したモジュールで構成されています:CCP(Console Command Processor)、BDOS(Basic Disk Operating System)、CBIOS(Custom Basic Input Output System)。一般的に CCP + BDOS は標準的で、CBIOS は基盤となるハードウェアに合わせてカスタマイズされます。

3 つのコンポーネントはすべてフロッピーディスクからブートストラップされ、メモリ(MZ80K/A では 0x9C00)に読み込まれ、制御が CBIOS に渡され、CBIOS がマシンをセットアップしてから CCP に制御を渡します。通常の動作条件下では、読み込まれたアプリケーションは BDOS を呼び出して、コンソールへの書き込み、キー入力の取得、ディスクアクセスなどのサービスを明確に定義された API から利用しますが、BDOS サービスが不要な場合は CBIOS を直接呼び出してその API を使用し、CCP+BDOS の RAM を使用して追加のプログラムスペースを確保することができます。アプリケーションが完了すると、ベクター 0x0000 にジャンプして CCP+BDOS の再読み込みを含むウォームスタートが開始されます。

CP/M は自己修正/組み込み変数を使用するため ROM への格納には適していませんが、CBIOS については話が別です。CBIOS を ROM に配置して RAM を増やすことが可能で、ページ ROM バンクを持つ Rom Filing System にアクセスできることもあり、私はこの方法を採用しました。

CBIOS を作成するには、以下の API メソッドを提供する必要があります:

API Method Description
BOOT コールドスタート。CCP を呼び出す前にすべてのハードウェアを初期化する。
WBOOT ウォームスタート。ハードウェアの変更を元に戻してから、CCP を呼び出す前に CCP+BDOS を再読み込みする。
CONST コンソールステータス。キーボードのキー入力が読み取り待ちかどうかを確認する。
CONIN コンソール入力。キーボードからキーを取得し、利用可能でない場合は待機する。
CONOUT コンソール出力。画面に文字を出力する。
LIST リストデバイス出力。リストデバイス(例:プリンター)に文字を出力する。
PUNCH パンチデバイス出力。パンチデバイスに文字を出力する(そう、70 年代にはパンチテープやカードが使われていた)!
READER リーダー入力。リーダーデバイス(例:紙テープ)から文字を入力する!
HOME 現在選択されているディスクのヘッドをトラック 0 に移動する。
SELDSK ディスクを選択/有効化する。
SETTRK 次の読み書き操作のディスクトラックを設定する。
SETSEC 次の読み書き操作の、選択されたトラック上のディスクセクターを設定する。
SETDMA データが読み書きされる場所であるディスクメモリアドレスを設定する。
READ ディスクセクターを読み取る。
WRITE ディスクセクターに書き込む。
LISTST リストデバイスステータス。リストデバイスが新しい文字を受け入れる準備ができているかを確認する。
SECTRN セクター変換。特定のハードウェアへの適応やディスクサブシステムの応答性向上のための、論理から物理へのセクター変換。
単純な要件のように見えますが、MZ80A のようなマシンには独自の BIOS がなく、CP/M 動作時に ROM のファームウェアが 0xC000 に移動されるため使用できないことを考慮する必要があります。また、フロッピー制御ファームウェアは非常に基本的で、ディスクのブートストラップのみを扱います。

CP/M が提供する基本的な文字入出力メカニズムの上に必要なさらなる要件として、ほとんどのアプリケーションは、高度な画面とキーボード機能を提供するスマートターミナルが CP/M マシンの前にあることを期待しています。これは通常 DEC VT52 や VT100 などのターミナルの形式です。MZ80A は独自の画面とキーボードを持っているため、このスマート機能を作成する必要があります。

したがって、CBIOS を作成するには、以下のファームウェアサブモジュールをコーディングする必要があります:

Sub-Module Description
基本画面 I/O 画面に文字を配置する、画面をクリアするなどの低レベル機能。
高度な画面 I/O 表示出力の位置決め、画面の一部のクリア、太字などの特別属性のインテリジェンス。
キーボード I/O キーコードをスキャンして返し、必要に応じて ASCII にマッピングする。
ディスク I/O 複数のディスクセクターを読み書きする機能を提供する。
以前に Sharp SA-1510 モニターを逆アセンブルしていたため、基本的な画面とキーボード機能を提供するための良い出発点がありました。フロッピーディスク AFI ファームウェアの逆アセンブルから、フロッピーディスクの読み取りに必要なコードの洞察が得られ、特にその欠点も明らかになりました。MZ80A は 2MHz コンピューターで、ディスク入出力ストリームを処理するだけの速度がなく、FDC のデータリクエスト/レディ信号に基づいて ROM バンクをページするハードウェアに依存しています。したがって、FDC コンポーネントには大幅な作業が必要でした。高度な画面 I/O については ANSI 標準を使用することにし、Ewen McNeill の Amstrad CPC ターミナルエミュレーターを採用しました。当初は彼の ANSI パーサーを単純に抽出して組み込めると思っていましたが、これは大量の作業になりました。最も簡単に見えるオプションが最も難しい場合があります!

すべての機能はスペースを必要とし、以下のように割り当てられています:

ROM Address Description
4K MROM(0x0000 - 0x0FFF から再配置されたモニター ROM) 0xC000 - 0xCFFF CBIOS(CP/M API、初期化ルーチン、ROM ディスクコントローラールーチン、割り込みルーチン)を提供。
2K Paged ROM 0xE800 - 0xEFFF, Bank 12 基本的なサウンドとメロディー、RTC、キーボードとヘルパー機能。
2k Paged ROM 0xE800 - 0xEFFF, Bank 13 画面 I/O と ANSI ターミナルパーサー。
2k Paged ROM 0xE800 - 0xEFFF, Bank 14 SD カードコントローラー機能。
2k Paged ROM 0xE800 - 0xEFFF, Bank 15 フロッピーディスクコントローラー機能。

CP/M ディスクドライブ

この CP/M と Custom BIOS の実装は 3 つの異なるディスクドライブコントローラーを使用し、そのうちのいくつかは常に存在するとは限らないため、ドライブはコールドブート中に CP/M 内で動的に作成されます。

ドライブの順序は以下の表に示されています。MZ80AFI カード経由で読み取られるオリジナルの MZ-80K(および MZ-80A)CP/M ディスクは、この表のフロッピーディスクドライブとして表示されます。ROM ドライブや SD カードも存在する場合は、通常 C: および D: になります。

Rom Drive # Present 0 1 2 Present 0 1 2
Rom Drive n/a   A A,B n/a   A A,B
Floppy Disk Yes A,B B,C C,D No      
SD Card Yes C,D,E,F D,E,F E,F,G Yes A,B,C,D,E B,C,D,E C,D,E,F
SD Card No       Yes      
ドライブ数の制限は、CP/M(最大 16 ドライブ)と、リポジトリの CPM_Definitions.asm ファイル内で設定される変数 'CSVALVEND - CSVALVMEM' で管理される、ドライブに割り当てられた RAM の量によって決まります。ドライブの割り当ては動的で、割り当てるメモリが多いほど利用可能なドライブが増えます。SD カードには数百の 16MB SD ディスクドライブを含めることができるため、問題は純粋にそれらの使用に割り当てられた RAM です。

機能

標準的な BIOS 機能に加えて、以下の機能が CBIOS に追加されています。

  • 50mS 精度のリアルタイムクロック
  • バッファと自動リピートを持つ割り込み駆動キーボード
  • 通常、Caps Lock、Shift Lock の 3 モードキーロック
  • ANSI ターミナル機能
  • 1.44M、720K、320K サイズの再ターゲット可能なフロッピーディスクドライブ
  • MZ80AFI カード経由でのオリジナル(未変換)MZ-80K CP/M ディスクの直接ブートおよび読み取り。セクターサイズで自動検出され、ドライブ C:/D: としてマウントされます
  • 240K サイズの再ターゲット可能な ROM ドライブ(設定で変更可能)
  • 再ターゲット可能な SD カード 16Mb ハードディスク
  • SHIFT+GRAPH+BREAK でモニターに終了

自動セットアップとビルド(推奨)

RFS 用の CP/M は通常の RFS ビルドの一部としてアセンブルおよびパッケージ化されるため、CBIOS、CP/M MZF アプリケーション、CP/M ディスクイメージを生成する最も簡単な方法は、お使いのプラットフォーム用の自動セットアップスクリプトです。各スクリプトは自己完結型です — お使いの OS 用の 1 ファイルだけをコピーして実行してください。前提条件をインストールし、RFS リポジトリをクローンし、約 110 MB のコンテンツバンドル(CP/M ソフトウェアを含む RFS_Files.zip)を取得し、初回ビルドも実行できます。ツールチェーンの詳しい知識は不要です。以下の手動によるツールごとの手順は、上級ユーザーおよび部分的なリビルド向けです。
Script Platform Notes
setup_RFS.sh macOS / Linux / WSL Java JRE(GLASS アセンブラー)、C ツールチェーン + make(同梱の cpmtools サブモジュールをコンパイル)、perl、git、unzip、curl、および(macOS では)GNU coreutils をインストールします。初回ビルドは ./build.sh -m です。
setup_RFS_windows_native.ps1 Windows 10 / 11 — ネイティブ、WSL 不要(推奨) winget を使用して Git for Windows と Temurin 17 JRE をインストールし、Git Bash を通じてビルドします。C コンパイラーは不要です — ビルド済みの tools\cpmcp.exe と tools\sdtool.exe が同梱されています。
setup_RFS_windows.ps1 Windows 10 / 11 — WSL2 / Ubuntu 経由 WSL2 + Ubuntu がない場合はインストールし(一度だけ再起動)、その後 Ubuntu 内で setup_RFS.sh を実行します。

macOS / Linux / WSL — setup_RFS.sh

chmod +x setup_RFS.sh
./setup_RFS.sh

Windows 10 / 11(ネイティブ — 推奨)— setup_RFS_windows_native.ps1、PowerShell プロンプトから:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\setup_RFS_windows_native.ps1

Windows 10 / 11(WSL2 経由)— setup_RFS_windows.ps1、管理者 PowerShell から:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\setup_RFS_windows.ps1

スクリプトは環境変数 RFS_REPO_URL(デフォルト https://git.eaw.app/eaw/RFS.git)と RFS_FILES_URL(コンテンツバンドルの場所)を尊重し、対話的プロンプトを上書きできます。ビルドは、Monitor/User ROM イメージ(CP/M CBIOS と CP/M MZF アプリケーションが組み込まれたもの)と、CP/M ディスクイメージを含む SD カードイメージを roms/ ディレクトリに書き込みます。ステップバイステップの完全な手順については RFS テクニカルガイド — ビルドシステム を参照してください。


CP/M のビルド

CP/M のビルドは、Z80 アセンブリ言語ソースをマシンコードバイナリにアセンブルし、ブートディスクを作成すること、あるいはこの実装の場合は ROM ベースの CBIOS と ROM に格納された MZF フォーマットのブータブルアプリケーションを作成することを含みます。

これを実現するにはいくつかのツールが必要で、現時点ではかなり手動のプロセスです。

パス

読みやすくするため、以下の短縮名はこの章の対応するパスを指しています。

Short Name  
[<ABS PATH>] このリポジトリがシステムに展開されたパス。
<software> [<ABS PATH>]/MZ80A_RFS/software
<roms> [<ABS PATH>]/MZ80A_RFS/software/roms
<CPM> [<ABS PATH>]/MZ80A_RFS/software/CPM
<tools> [<ABS PATH>]/MZ80A_RFS/software/tools
<MZF> [<ABS PATH>]/MZ80A_RFS/software/MZF
<MZB> [<ABS PATH>]/MZ80A_RFS/software/MZB

ツール

すべての開発は Linux、特に Debian/Ubuntu で行われています。Windows は RAM のフラッシュと GUI 版の CP/M ツールの使用に利用していますが、Windows での RFS のビルドには時間を割いていません。いずれ必要なツールがすべてインストールされた Docker イメージを作成する予定ですが、それまでの間、Z80 コードのアセンブル、C プログラムの作成、CP/M ソフトウェアと CP/M ディスクイメージの操作のために以下のツールを入手してインストールする必要があります。

Z80 Glass Assembler - アセンブリファイルをマシンコードに変換する Z80 アセンブラー。
samdisk - マルチ OS コマンドライン低レベルディスク操作ツール。
cpmtools - マルチ OS コマンドライン CP/M ディスク操作ツール。
CPMToolsGUI - Windows ベースの GUI CP/M ディスク操作ツール。
z88dk - Z80 CPU 向けの優れた C 開発キット。
sdcc - Z80 をターゲットの一つとする別の優れた Small Device C コンパイラー。z88dk はこのツールの Z80 向け強化版をパッケージ内に提供しています。

ソフトウェア

ソフトウェアイメージのビルドは、リポジトリをクローンし、提供されているシェルスクリプトとバイナリをいくつか実行することで行えます。

Script Description
assemble_cpm.sh CPM バイナリ、RFS 経由で読み込むための CPM MZF フォーマットアプリケーション、CPM ROM ドライブ 0 と 1 をビルドするシェルスクリプト
assemble_rfs.sh Rom Filing System ROM イメージをビルドする bash スクリプト。
assemble_roms.sh SA-1510 モニター ROM などの標準 MZ80A ROM をすべてビルドする bash スクリプト。
make_roms.sh 512KByte フラッシュ RAM にプログラミングするのに適した RFS ROM をビルドする bash スクリプト。これらのイメージには、バンク化された RFS ROM、SA-1510 などの各種システム ROM、および RFS が読み込むすべての MZF プログラムが含まれます。
make_cpmdisks.sh SD カードまたは ROM ドライブのロー形式イメージと、フロッピーディスクエミュレーターでの使用や物理媒体へのコピー用の CPC Extended Disk Format の両方として、CPM ディスクセットをビルドする bash スクリプト。
make_sdcard.sh RFS イメージといくつかの CPM ディスクドライブを組み合わせた SD カードイメージを作成する bash スクリプト。このイメージはバイナリ形式で SD カードにコピーされ、RFS SD カードリーダーに取り付けられます。
mzftool.pl MZF イメージを作成/抽出/操作する Perl スクリプト。
processMZFfiles.sh MZF プログラムのセットを Rom Filing System ROM での使用に適したセクター化イメージに変換する bash スクリプト。
sdtool src/tools リポジトリで作成されたバイナリ。RFS SD カードイメージを構築し、ディレクトリを作成して MZF/バイナリアプリケーションをドライブイメージに追加します。

CP/M システムは 4 つの部分でビルドされます:

1. CCP、BDOS、CBIOS スタブを含む cpm22.bin。
2. プライマリソースが 4K ROM と 4 つのバンク化された 2K ROM にあるバンク化された CBIOS。
   これらは RFS Banked Monitor ROM と Banked User ROM に追加するために
   生成されます。
3. 任意の CP/M ドライブ文字に割り当てられる、最大 2 つ(現在)の読み取り専用
   CP/M ROM ドライブ。
4. 1. と 3. で生成されたバイナリを、Rom Filing System に
   単なる別のプログラムとして直接追加するのに適したセクター化 MZF イメージへの変換。

上記のすべては assemble_cpm.sh bash スクリプトにエンコードされており、以下のように実行できます:

cd <software>
tools/assemble_cpm.sh

このスクリプトは現在 1 つの読み取り専用 CPM ROM ドライブを生成するように設定されています。2 つ目の CPM ROM ドライブを追加するには、以下の手順に従ってください:

1. <tools>/make_cpmdisks.sh スクリプトを編集し、
   変数を変更します:
   from BUILDCPMLIST="cpm22 CPM_RFS_1"
   to   BUILDCPMLIST="cpm22 CPM_RFS_1 CPM_RFS_2"

   変数を変更します:
   from SOURCEDIRS="CPM_RFS_[1] CPM[0-9][0-9]_* CPM_MC_5 CPM_MC_C? CPM_MC_D? CPM_MC_E? CPM_MC_F? CPM[0-9][0-9]_MZ800*" to
   to   SOURCEDIRS="CPM_RFS_[1-2] CPM[0-9][0-9]_* CPM_MC_5 CPM_MC_C? CPM_MC_D? CPM_MC_E? CPM_MC_F? CPM[0-9][0-9]_MZ800*"
   
2. ディレクトリを作成します(存在しない場合):
   <CPM>/CPM_RFS_2

3. ROM に配置する必要な CPM ファイルをそのディレクトリに入れます。

4. make_cpmdisks.sh スクリプトを実行するか、以下に列挙するコマンドシーケンスの一部としてイメージをビルドします。

CPM を使用するには、2×512KByte フラッシュ RAM にプログラミングできる MonitorROM と USERROM イメージを作成する必要があります。以下のコマンドを発行して、CPM を、ROM 内のすべての RFS、ROM、アプリケーションとともにビルドします:

cd <software>
tools/assemble_cpm.sh
tools/assemble_rfs.sh
tools/assemble_roms.sh
tools/make_cpmdisks.sh
tools/make_roms.sh
tools/make_sdcard.sh

上記コマンドの出力は ROM イメージ <roms>/MROM_256.bin と <roms>/USER_ROM.256.bin で、512Kbyte フラッシュ RAM にフラッシュし、RFS アダプターのソケットに挿入する必要があります。

CPM ディスクイメージは、ロー形式イメージは <CPM>/1M44/RAW に、CPC Extended フォーマットディスクイメージは <CPM>/1M44/DSK にあります。これらのイメージは <CPM> 内のディレクトリからビルドされ、CPM* で始まる各ディレクトリが 1 つの 1.44MB ドライブイメージにパッケージ化されます。なお、加えて、これらのディレクトリはサポートされる他のすべてのディスクにも、対応するディレクトリ内のイメージとしてパッケージ化されます。例えば 16MB SD カードドライブイメージは <CPM>/SDC16M です。

SD カードイメージは <roms>/SHARP_MZ80A_RFS_CPM_IMAGE_1.img にあり、先頭に RFS ディスクイメージ <roms>/SHARP_MZ80A_RFS_IMAGE_1.img を含み、続いて 7 つの CPM フォーマットドライブイメージが続きます。これらは上記のとおり <CPM>/SDC16M/RAW に格納されています。これらのイメージは <CPM> 内のディレクトリからビルドされますが、make_cpmdisks.sh スクリプト内にハードコードすることで最終イメージに手動で追加されます。

ROM ドライブに格納されるアプリケーションは <MZF> ディレクトリにあります。ROM に入れたいアプリケーションをこのディレクトリにコピーし、以下のコマンドを発行して、それらを <MZB> ディレクトリに格納されるセクター単位に丸めたイメージに処理します。

cd <software>
tools/processMSFfiles.sh

ROM に組み込まれる実際のアプリケーションは <tools>/make_roms.sh スクリプトで選択されます。このスクリプトは必要なすべてのアプリケーションを列挙し、スペースが許す限り多くを ROM にパックします。アプリケーションが確実に ROM に表示されるようにするには、リストの先頭に追加します(.MZF 拡張子なしのファイル名のみ)。例:

ファイル <tools>/make_roms.sh を編集します
行を見つけます: ROM_INCLUDE=
この行の下に、次の形式でアプリケーションを追加します: ROM_INCLUDE+="${MZBPATH}/<YOUR APPLICATION>.${SECTORSIZE}.bin"
例: ROM_INCLUDE+="${MZB_PATH}/A-BASIC_SA-5510.${SECTORSIZE}.bin:"
ファイルを保存し、上記のコマンドを実行して MonitorROM と USERROM をビルドします。

ディスクフォーマット

わかったことですが、CP/M ディスクフォーマットは数百もあり、Sharp シリーズだけでもマシンごとに 2〜3 種類実装されています。この CP/M 実装に使用するフォーマットを決定するにあたり、既存のフォーマットを調べました。オリジナルの Sharp MZ80A ディスクにアクセスできず、しかもそれらはいずれにせよ反転された非標準フォーマットであること、MZ80B が MZ80A に似ているもののわずかに容量が大きいこと、MZ800 がハイブリッドであること、MZ80K が低容量であることから、Sharp MZ80A ディスクと同じ物理フォーマットである 1.44MB、720K の 3.5” フロッピー、および ROM ベースの 240K ROM ドライブの標準フォーマットを使用することにしました。

使用しているフォーマットは以下の diskdefs 定義を使用して cpmtools で操作できます。上記を、cpmtools または CPMToolsGUI とともに配置されている diskdefs ファイルに入れて使用してください:

   # 320K Disk for the MZ80A - Same format as the MZ800
   # but implements a cylinder in uniform manner (ie. 1 cyl
   # = 1 track x 2(heads) where as the MZ800 implements as 
   # 160 tracks, 80 x Head 1 0->79 then 80 x Head 2 80->159.
   diskdef MZ80A-A
     seclen 256
     tracks 40
     sectrk 32
     blocksize 2048
     maxdir 64
     skew 0
     boottrk 1
     os 2.2
   end
   
   # A standard format 1.44Mb Floppy format for the MZ80A
   diskdef MZ80A-1440
     seclen 512
     tracks 80
     sectrk 36
     blocksize 2048
     maxdir 128
     skew 0
     boottrk 0
     os 2.2
   end
   
   # A standard format 720K Floppy format for the MZ80A.
   diskdef MZ80A-720
     seclen 256
     tracks 80
     sectrk 36
     blocksize 2048
     maxdir 128
     skew 0
     boottrk 0
     os 2.2
   end

   # A 240K Rom Filing System ROM Drive image.
   diskdef mz80a-rfs
     seclen 128
     tracks 15
     sectrk 128
     blocksize 1024
     maxdir 32
     skew 0
     boottrk 0
     os 2.2
   end

   # A 16Mb fixed disk SD Card Image.
   diskdef MZ80A-SDC16M
     seclen 512
     tracks 1024
     sectrk 32
     blocksize 8192
     maxdir 512
     skew 0
     boottrk 0
     os 2.2
   end   
CP/M 内では、これらの物理ディスクフォーマットはディスクパラメータブロックで以下のように表現されます。通常、これらの設定や上記の diskdefs について気にする必要はありませんが、独自のカスタムフォーマットを追加する必要がある場合に知っておくと便利です:
Definition MZ80A 320K Rom Filing System 1.44MB 3.5” 720K 3.5” 16MB SD Card Image
SPT 64 128 144 72 128
BSH 4 3 4 4 6
BLM 15 7 15 15 63
EXM 1 0 0 0 3
DSM 155 240 719 359 2047
DRM 63 31 127 127 511
AL0 128 128 192 192 192
AL1 0 0 0 0 0
CKS 16 8 32 32 0
OFF 1 0 0 0 0
既存の Sharp CP/M プログラムを使用するには、プログラムをディスクから抽出し、この実装が認識するフォーマットに追加する必要があります。このため、以下のセクションでは関連するマシンのディスクからデータを抽出する方法を説明します。

CP/M ディスクの作成

開発では、Sharp MZ80-AFI インターフェースカードに接続した Lotharek HxC Floppy Emulator を使用しました。この構成を使用すると、Sharp MB8866 フロッピーディスクコントローラーが通信できる任意のディスクドライブをエミュレートできます。これが、これらのドライブが今でも入手可能でほとんどの CP/M 操作に十分な容量を持つことから、3.5" フォーマットにたどり着き、テストした方法です。

この CP/M 実装で Sharp MZ80A 上で使用できる CP/M ディスクを作成するには、上記の定義を cpmtools の diskdefs ファイルに追加する必要があります。追加したら、\<CPM\>/BLANKFD 内のブランクイメージの 1 つを新しい名前にコピーしてターゲットディスクとして使用するか、ディスク定義を使用して CPMTools 内から作成します。次に、必要なプログラムを新しいディスクに追加します。CPMToolsGUI ではこれは単なるドラッグアンドドロップの手順です。

新しいロー形式 CP/M イメージをフロッピーエミュレーターや実際のフロッピーディスクドライブで使用するには、ローイメージをほとんどのフロッピーディスクツールがフロッピーに読み書きできるフォーマットに変換する必要があります。Lotharek フロッピーエミュレーターの場合、ツール HxCFloppyEmulator v2.2.2.1 を使用して Load と Export to HFE を行うと、実際のフロッピーを模倣する適切な SD イメージが生成されます。

イメージを変換するには、以下のいずれかを使用します:

1.44MB ドライブの場合:
./samdisk copy <RAW IMAGE FILE, ie. CPM00_SYSTEM.RAW> <DSK IMAGE FILE, ie.CPM00_SYSTEM.DSK> --cyls=80 --head=2 --gap3=78 --sectors=36 --interleave=4
Samdisk はファイルのサイズ(例:1474560 バイト)からフォーマットを自動的に認識します

720K ドライブの場合:
./samdisk copy <RAW IMAGE FILE, ie. CPM00_SYSTEM.RAW> <DSK IMAGE FILE, ie.CPM00_SYSTEM.DSK> --cyls=80 --head=2 --gap3=78 --sectors=36 --size=2 --interleave=4
Samdisk はファイルのサイズ(例:737280 バイト)からフォーマットを自動的に認識します

MZ80A 320K ドライブの場合:
./samdisk copy CPM00_320K_SYSTEM.RAW CPM00_320K_SYSTEM.DSK --cyls=40 --gap3=78 --head=2 --sectors=16
Samdisk はファイルのサイズ(例:327680 バイト)からフォーマットを自動的に認識します

RFS ROM ドライブは変換不要です。RFS 機能はロー形式イメージを前提としています。

注意:Samdisk v4 は使用しないでください。ディスクの先頭にランダムなセクターを配置するバグがあります。このバグのデバッグに何時間も失われました。samdisk
v3.8.8 を使用するのが最善です

上記の samdisk コマンドは、Lotharek HxCFloppyEmulator や物理フロッピーディスクを書き込むツールで読み取り処理できる Amstrad CPC Extended DSK フォーマットイメージを作成します。

MZ80A CP/M ディスクの抽出

Sharp MZ-80A はフロッピーディスクデータを反転フォーマットで保存します。ディスク上のすべてのバイトは実際のデータバイトのビット単位の補数です。これは MZ-80A のフロッピーディスクコントローラーのハードウェア特性であり、ロー形式ディスクイメージはすべてのバイトを最初に反転しないと CPMTools で直接読み取れないことを意味します。

オンラインで入手できるほとんどの MZ-80A CP/M ディスクイメージは EDSK(Amstrad CPC Extended DSK)フォーマットです。ディスクジオメトリは 40 シリンダー、2 ヘッド、トラックあたり 16 セクター、セクターあたり 256 バイト(合計 320KB)です。

samdisk を使用して EDSK イメージをフラットなロー形式イメージに変換します:

  samdisk copy <MZ80A DISK NAME>.DSK <MZ80A DISK NAME>.RAW --cyls=40 --head=2 --sectors=16 --size=256

以下のコマンドを実行してロー形式イメージのすべてのバイトを反転し、MZ-80A 反転フォーマットを CPMTools が処理できる標準データに変換します:

  python3 -c "import sys; sys.stdout.buffer.write(bytes(~b & 0xFF for b in open('<MZ80A DISK NAME>.RAW','rb').read()))" > <MZ80A DISK NAME>_normal.RAW

MZ80A-A diskdef(上記のディスク定義セクションで定義)を CPMTools とともに使用して、処理済みイメージからファイルを一覧表示および抽出します:

  # List files on the disk
  cpmls -f MZ80A-A <MZ80A DISK NAME>_normal.RAW

  # Copy all files to a local directory
  cpmcp -f MZ80A-A <MZ80A DISK NAME>_normal.RAW 0:*.* /output/directory/
抽出後、プログラムは CPMTools を使用してこの CP/M 実装がサポートするフォーマット(MZ80A-1440、MZ80A-720、MZ80A-A、mz80a-rfs)のいずれかの新しいディスクイメージに配置し、上記のCP/M ディスクの作成セクションで説明したように samdisk でフロッピーエミュレーターイメージに変換できます。物理 MZ-80A フォーマットディスクに書き戻す際は、バイト反転を逆方向に適用する必要があることに注意してください。

MZ80K CP/M ディスクの抽出

Sharp MZ-80K はフロッピーディスクに標準(非反転)データを使用するため、ビット反転は不要です。ただし、ディスクフォーマットは MZ-80A とは異なり、容量も低くなっています。MZ-80K は 5.25" 単密度片面ドライブを中心に設計されていました。MZ-80K CP/M ディスクのブートセクターは、最初のセクターの先頭にあるマーカーバイト 01h に続く ASCII 文字列 IPLPRO によって識別されます。

MZ-80K CP/M ディスクイメージは通常 EDSK またはロー形式で入手できます。ディスクジオメトリは 40 シリンダー、1 ヘッド、トラックあたり 18 セクター、セクターあたり 128 バイト(約 90KB)です。

samdisk を使用して EDSK ソースからロー形式イメージを抽出します:

  samdisk copy <MZ80K DISK NAME>.DSK <MZ80K DISK NAME>.RAW --cyls=40 --head=1 --sectors=18 --size=128
バイト反転は不要です。MZ-80K フォーマットに適した diskdef を使用して CPMTools でロー形式イメージを直接読み取ることができます。ここで示す CPMTools の方法は、ディスク内容のアーカイブや、ネイティブにサポートされている MZ-80A フォーマット(MZ80A-1440 や MZ80A-720 など)の 1 つへのファイル転送に依然として有用です。ただし、RFS CP/M CBIOS は MZ80AFI カード経由でオリジナルの MZ-80K CP/M ディスクを直接読み取ることもできるようになりました(上記のCP/M ブートプロセスを参照)。ディスクは 128 バイトのセクターサイズによって自動検出され、CP/M ドライブ(通常は C:/D:)としてマウントされるため、実機や picoZ80 での日常的な使用ではディスクを事前に変換する必要はもうありません。
  # List files (adjust diskdef name to match your MZ-80K diskdef entry)
  cpmls -f mz80k <MZ80K DISK NAME>.RAW

  # Extract all files
  cpmcp -f mz80k <MZ80K DISK NAME>.RAW 0:*.* /output/directory/

MZ80B CP/M ディスクの抽出

Sharp MZ-80B は MZ-80A と同様に、フロッピーディスクデータを反転フォーマットで保存します。ディスク上のすべてのバイトは実際のデータのビット単位の補数です。MZ-80B のブートセクターは、最初のセクターの先頭にあるマーカーバイト 03h に続く IPLPRO によって識別され、MZ-80A(01h)や MZ-80K(01h)のバリアントと区別されます。

MZ-80B は MZ-80A よりわずかにディスク容量が大きく、40 シリンダー、2 ヘッド、トラックあたり 18 セクター、セクターあたり 256 バイト(約 368KB)を使用します。入手できるほとんどのディスクイメージは EDSK フォーマットです。

samdisk を使用して EDSK イメージをフラットなロー形式イメージに変換します:

  samdisk copy <MZ80B DISK NAME>.DSK <MZ80B DISK NAME>.RAW --cyls=40 --head=2 --sectors=18 --size=256

MZ-80A と同じバイト反転を適用して、反転データを標準フォーマットに変換します:

  python3 -c "import sys; sys.stdout.buffer.write(bytes(~b & 0xFF for b in open('<MZ80B DISK NAME>.RAW','rb').read()))" > <MZ80B DISK NAME>_normal.RAW
適切な MZ-80B diskdef を使用して CPMTools で処理済みのロー形式イメージからファイルを一覧表示および抽出します。抽出後、CP/M ディスクの作成セクションで説明したように、RFS で使用するためにプログラムをサポートされている MZ-80A フォーマットのディスクイメージにコピーします。
  # List files (adjust diskdef name to match your MZ-80B diskdef entry)
  cpmls -f mz80b <MZ80B DISK NAME>_normal.RAW

  # Extract all files
  cpmcp -f mz80b <MZ80B DISK NAME>_normal.RAW 0:*.* /output/directory/

MZ800 CP/M ディスクの抽出

MZ800 シリーズのコンピューターは、ブートトラックに反転データ、CP/M トラックに標準データを使用する混合フォーマットのディスクを使用します。さらに悪いことに、トラックの順序はヘッド 0 をトラック 0〜39、ヘッド 1 をトラック 40〜79 として配置するようになっています。これらのディスクを使用するには、この奇妙なフォーマットに対応するための追加コードを加える意味がないと考えるため、データを抽出して私が作成したフォーマットの 1 つにコピーするのが最善です。

samdisk を使用して EDSK(Amstrad CPC マシン向けに作成された Extended DSK フォーマット。ほとんどの MZ800 ディスクはこのフォーマットのようです)をロー形式イメージに変換します。

  samdisk copy <MZ800 DISK NAME>.DSK <MZ800 DISK NAME>.RAW --cyls=40 --head=2 --sectors=8 --size=256

以下の bash コマンドを実行して、上記で得たロー形式ディスクを CPMTools が読み取れるものに変換します。

   mv <MZ800 DISK NAME>.RAW workingfile.raw
   > total
   dd if=workingfile.raw of=total count=8192 bs=1
   for i in $(seq 8192 8192 327680); do 
     dd if=workingfile.raw of=blob skip=$i bs=1 count=4096
     cat blob >> total
     echo $i
   done
   for i in $(seq 12288 8192 327680); do
     dd if=workingfile.raw of=blob skip=$i bs=1 count=4096
     cat blob >> total
     echo $i
   done
   mv total <MZ800 DISK NAME>.RAW

処理済みのロー形式イメージからデータを読み取るには、以下の diskdefs 定義が必要です。

   # Definition for the MZ800 CP/M Boot Disk. The reserved
   # track is in inverted data format but this is skipped in
   # CPM Tools.
   diskdef mz800-BOOT
     seclen 256
     tracks 80
     sectrk 16
     blocksize 2048
     maxdir 64
     skew 0
     boottrk 1
     os 2.2
   end

   # Definition for the MZ800 CP/M Data disk. No reserved tracks.
   diskdef mz800-DATA
     seclen 256
     tracks 80
     sectrk 16
     blocksize 2048
     maxdir 64
     skew 0
     boottrk 0
     os 2.2
   end

CP/M アーカイブ

CP/M アーカイブはファイルの保存/アーカイブの場所ではないため、Gitea から削除しました。必要な場合はzip ファイルをダウンロードし、<repo>/software ディレクトリに解凍してください。

アーカイブ内のファイルは厳選されたプログラムで、様々な CP/M アーカイブから集められ、CPM[0-9[0-9]_ という命名規則のディレクトリに組み立てられています。 また、Grant Searle の MultiComp コンピューター由来のもの(およびアーカイブを組み立てた彼の作業に対する正当なクレジットと著作権 (C))も含まれています。MultiComp は複数のコンピューター(または複数の CPU タイプ)を 1 つにまとめたもので、そのモードの 1 つが CP/M を実行します。Grant のアーカイブは優れており、MZ80A 上で CP/M を使用するための理想的なベースです。

アーカイブを 3.5” ドライブやフロッピーエミュレーターで使用するのに適した 1.4MB フロッピーイメージのセットにビルドするには、以下のコマンドを実行します:

cd <software>
tools/make_cpmdisks.sh

ディスクはディレクトリ <CPM>/1M44/DSK に作成されます。

このスクリプトは、アーカイブの組み合わせを使用して 16MB SD カードドライブイメージもビルドします。組み合わせはスクリプト内にハードコードされています。

CP/M マニュアル

Manual Description
User Manual CP/M v2.2 ユーザーマニュアル。
SID Symbolic Instruction Debugger ユーザーガイド。
ED EDitor ユーザーガイド。
MAC Macro Assembler ユーザーガイド。
ASM Z80/8080 Assembler ユーザーガイド。
DDT Dynamic Debugging Tool ユーザーガイド。

開発者ガイド

Sharp MZ 上の CP/M の内部アーキテクチャの理解、CBIOS の変更、新しいディスクフォーマットの追加、ソースからのビルドを希望する開発者向けに、包括的なCP/M 開発者ガイドが用意されています。CCP/BDOS/CBIOS のレイヤリング、RFS と TZFS 両プラットフォームのメモリマップ、ディスクパラメータブロック、ANSI ターミナルエミュレータ、ストレージコントローラ、ビルドシステム、CI/CD パイプラインを網羅しています。

クレジット

サードパーティの設計に基づいたり使用したりしたコンポーネントについては、ヘッダー内にオリジナル作者の著作権表示を含めるか、正当なクレジットを記載しています。すべてのサードパーティソフトウェアは、私の知る限りおよび調査した限りではオープンソースで自由に使用可能です。ライセンス制限のあるコンポーネントが見つかった場合は、このリポジトリから削除し、適切なリンク/設定を提供します。

ライセンス

この設計(ハードウェアおよびソフトウェア)は GNU Public Licence v3 の下でライセンスされています。

The Gnu Public License v3

このプロジェクト内で GPL v3 とマークされているソースおよびバイナリファイルはフリーソフトウェアです:Free Software Foundation が発行する GNU General Public License の条項の下で、ライセンスのバージョン 3、または(任意で)それ以降のいずれかのバージョンに従って、再配布および/または改変することができます。

これらのソースファイルは有用であることを期待して配布されますが、いかなる保証もありません。商品性や特定目的への適合性の暗黙の保証さえありません。詳細は GNU General Public License を参照してください。

このプログラムとともに GNU General Public License のコピーを受け取っているはずです。受け取っていない場合は、http://www.gnu.org/licenses/ を参照してください。