2022年11月13日日曜日

パソピア7/700用のFDフォーマッタ

パソピア7/700用フロッピーディスクのフォーマットプログラムを作ってみる。

BIOSでFDDを制御するためには、まずパラメータのセット(Fn#=18)が必要
・Cレジスタ:Function(Fn)#=18(FDDパラメータセット)
・HLレジスタ:Buffer先頭アドレス
・Dレジスタ:Track#
・Eレジスタ:Sector#
・Bレジスタ:Read/Write Sector数
・Aレジスタ:FDD Paramter
 - bit7:Side (0 or 1)
 - bit6-5:00...両面倍密度, 01...片面倍率度, 10...両面単密度, 11...片面単密度
 - bit4-3:00固定
 - bit2-0:装置番号-1 (0-3)

FDDパラメータセット(Fn#=18)後、以下いずれかのFn#で再びBIOSコール
・Fn#=19:Disk Read(Seek & Read)
・Fn#=20:Disk Write(Seek & Write)
・Fn#=21:Disk Write(Seek & Write with Check)
・Fn#=22:Disk Write Delete(Seek & Write Delete)
・Fn#=23:Disk Restore(Seek to Zero)
・Fn#=24:Disk Format(Seek & Write ID)
・Fn#=25:Disk Check(Check Disk Status)
BIOSコールから戻ってきた際に、キャリーフラグが立つとエラー発生。
・Aレジスタ:終了ステータス
 - "0"=30h:正常
 - "1"=31h:Not Ready
 - "8"=38h:Write Protect
 など。
エラー時のリトライは1回ずつ入れることにした。

アンフォーマットのフロッピーだと、最初にトラック毎にIDの書き込みが必要。
IDを書かずにデータ書き込みするとID errorで失敗する。

フォーマット処理フローは以下の通り
(1) 装置初期化
・Fn#18でパラメータセット
 - Aレジスタ:FDD Paramter=装置番号-1(0-3)をセット
・Fn#23でDisk Restore
 - Aレジスタ:FDD Paramter=07hをセット

(2) トラック毎にID書き込み
・Fn#=18でパラメータセット
 - HLレジスタ:ID Buffer先頭アドレス。バッファには以下104バイトを書き込んでおく
  - 1バイト目:Track#
  - 2バイト目:Side0(00h) or Side1(01h)
  - 3バイト目:Index(01h→1Ah)
  - 4バイト目:単密度(00h) or 倍密度(01h)
  →上記を26回繰り返し4バイト×26回=合計104バイト
 - Dレジスタ:Track#
 - Eレジスタ:Sector#=E5h
 - Bレジスタ:Read/Write Sector数=40h
 - Aレジスタ:FDD Paramter=装置番号-1(0-3)をセット(Side1は+80h)
・Fn#24でWrite ID
 - Aレジスタ:FDD Paramter=8Dhをセット

(3) Disk読み込みチェック
・Fn#=18でパラメータセット
 - HLレジスタ:Read Buffer先頭アドレス。
  - 読み込み用に16セクタ(最大4,096バイト)分のバッファを用意しておく
 - Dレジスタ:Track#
 - Eレジスタ:Sector#=01h
 - Bレジスタ:Read/Write Sector数=10h
 - Aレジスタ:FDD Paramter=装置番号-1(0-3)をセット(Side1は+80h)
・Fn#=23でDisk Seek & Read
 - Aレジスタ:FDD Paramter=30hをセット

(4) Track0.Side0→Track0.Side1→Track1.Side0→Track1.Side1→...
→Track34.Side0→Track34.Side1の順番で(2)(3)を繰り返し。
但しTrack18のWrite ID後、ディレクトリ・ディスク属性・FATをSide0に書き込み
・Fn#=18でパラメータセット
 - HLレジスタ:Read Buffer先頭アドレス。
  - バッファにはディレクトリ・ディスク属性・FATを書き込んでおく
 - Dレジスタ:Track#=12h
 - Eレジスタ:Sector#=01h
 - Bレジスタ:Read/Write Sector数=10h
 - Aレジスタ:FDD Paramter=装置番号-1(0-3)をセット
・Fn#=21でDisk Write with Check
 - Aレジスタは変更なし

(5) Disk Restore
・Fn#18でパラメータセット
 - Aレジスタ:FDD Paramter=装置番号-1(0-3)+80hをセット
・Fn#23で装置初期化
 - Aレジスタ:FDD Paramter=07hをセット

上記の流れで処理を組んでコンパイル。できたバイナリをBASICと組み合わせ。
パソピア7のエミュレータで確認。
うまく行ったっぽい。
エミュが作成したd88イメージをバイナリエディタで確認したが、問題なさそう。

初代パソピアT-DISK BASICでの読み書きもエミュレータで確認。
パソピア7でフォーマットしたディスクは、初代パソピアでも使えそう。

実機での動作確認はパソピア700。フォーマット、データ読書きも大丈夫そう。

FDフォーマッタのRAMPACイメージとBASICテキストをアップしました。

パソピア7と初代パソピアはエミュレータでしか確認できていないので、すぐ試せる方は試して報告してもらえると助かります。

2022年11月12日土曜日

パソピアのフロッピーフォーマット

以前の投稿で パソピアのフロッピーをイメージ化する手順をまとめたが、今回はフロッピーの内部フォーマットについて調べてみたので備忘録。
パソピアには片面ミニフロッピーもあるが、今回は両面倍密(2D)ミニフロッピーについて。

・2ヘッド:Side0, Side1
・35トラック:Track#0(外周)~#34(内周)
・1トラックあたり16セクタ:Sector#1~#16 (時計回り順)
・1セクタあたり256byte(倍密度) ※Track#0.Side0のみ128byte(単密度)
・8セクタ毎に1クラスタ。クラスタの並び順は、
 Side0.Sector1-8 → Side1.Sector1-8 → Side0.Sector9-16 → Side1.Sector9-16
 下の表の場合、セクタ順に並べたのでクラスタ順が0→2→1→3になっているのに注意。

・Track#0は未使用領域
・Track#18.Side0は、
 (a) Sector#1-12:ディレクトリ
 (b) Sector#13:ディスク属性
 (c) Sector#14-16:FAT(256byte)×3セット

初代パソピア用T-DISK BASICの場合は、以下の領域が使われている。
・Track#0.Side1.Sector#1-8:初期化ルーチン
・Track#1.Side0.Sector#2~Track#8.Side1.Sector#16:T-DISK BASICシステム
・Track#19.Side1.Sector#1~Track#34.Side1.Sector#16:漢字パターン

総容量は、2ヘッド×35トラック×16セクタ×256byte-(単密度分:16セクタ×128byte)
=284,672byte

Track#18.Side0の格納データにについて。
(a) Sector#1-12:ディレクトリ ... 16バイト毎に、ファイル情報が格納される
・0~9バイト:ファイル名
 - ファイル名に00h, FFh, 3Ah(":")は含んではならない
 - 0バイト目が00hならKILLされたファイル、FFhなら未使用
・10バイト:ファイル属性
 - 00h:ソース形式(JISコード)
 - 01h:マシン語
 - 80h:バイナリ(中間言語)形式
 - それぞれ10hを加えると書き込み禁止
・11バイト:クラスタ番号
・12~15バイト:未使用
・1セクタあたり16ファイルの情報が書き込めるので、12セクタで最大192ファイルの領域
・フォーマット直後はFFh埋め

(b) Sector#13:ディスク属性
・0バイト:ディスク属性
 - 00h:(SET 装置番号," ") 属性なし
 - 10h:(SET 装置番号,"P") 書き込み禁止(Write Protect)
 - 20h:(SET 装置番号,"E"?) EBCDIC(未使用)
 - 40h:(SET 装置番号,"R") 書き込み確認(Read after Write)
・1~255バイト:未使用(00h)
・フォーマット直後は00h埋め

(c) Sector#14-16:FAT(256byte)×3セット
・クラスタ(8セクタ)単位でFAT情報1バイトを格納
 - 00h~8Bh:Nextクラスタ番号(=FAT内ポインタ)
 - C1h~C8h:ラストクラスタ ※右4bitの1~8:有効セクタ数
 - FEh:Reserved
 - FFh:未使用クラスタ
・フォーマット直後は、0~3, 72, 74, 140~255バイトがFEh、それ以外はFFh。
 上記256バイトが、Sector#14,#15,#16に3セット書き込まれる。

FAT256バイトはクラスタ順で並んでいる。
上の表はセクタ順に並べたのでTrack#18でFEhが連続しているように見えるが、クラスタ順が入れ子になっているため、Track#18(72-75セクタ)のFATはFEh, FFh, FEh, FFhの並び。
紛らわしいので注意...

-----
(2023/1/29)表の一部が間違っていたので訂正。Track#0.Side0(Sector#1-16)が単密度