BSAVE / SAVEM 前史 #1 [プログラム]
2010/03/18 タイトルを変更しました
マシン語を使用したモノや BASIC のデータ領域/ワークエリア等を保存する方法として、まず最初に思いつくのはモニタモードでカセットテープに保存する方法ですが、これは速度も遅く信頼性も低いものでした。
「じゃあ、ディスクへの保存なら大丈夫だろう」と考えますが、最初期の Disk-BASIC には BSAVE / SAVEM 等のバイナリデータ保存用の命令はありませんでした。
APPLE II は別として、国産 PC で FM-8 以前にディスクへのバイナリデータのロード/セーブが可能だったモノってありましたっけ?
そう考えると APPLE II って偉大です。
BASIC にバイナリデータのロード/セーブ命令が無いといってバイナリデータを扱えなかった訳ではありません。
BASIC に精通した真のプログラマは、プログラムを組んで問題を解決するものです。
まず最初に思いつくのは、メモリから PEEK() 関数を使用して読み込んだデータをシーケンシャルファイルに出力する方法ですが、これには問題があります。
BASIC のリファレンスマニュアルにはあまり詳しく書かれていないのですが、シーケンシャルファイルで扱えるデータは基本的にテキストデータだけ(',' (コンマ)を除く 20H から 7EH と 80H から FFH まで)です。
シーケンシャルファイル入力で使用する INPUT # 命令は INPUT 命令と違いコンソールからではなくファイルから入力を行います。 しかし、これはコンソールからの入力と同様にコントロールコードが有効になっているのです。
INPUT 命令では入力時に CR / ',' (コンマ) はデータの区切り/終了を意味しますが、同様に INPUT # 命令でも入力される文字列中に LF / CR / ',' (コンマ)が現れるとデータの区切りとみなされるため、データとしては無視されてしまいます。 また、00H も無視されてしまいます。
N-BASIC では、
00H(Null), 07H(Bell), 0AH(LineFeed), 0BH(Home), 0CH(Clear), 0DH(CarriageReturn), 1CH(CursorRight), 1DH(CursorLeft), 1EH(CursorUp), 1FH(CursorDown)
が、影響を受けるコードです。
そのため、影響を受けるコードを正常に読み込むには、例えば 00H → \@, 07H → \G, \ → \\ という具合にエスケープシーケンスを使用して 20H 以上のコードに変換しておく必要があります。
これだとデータを取りこぼすことなく読み込めますが、文字列変数に格納されたデータを1文字づつ取り出してチェックし、エスケープシーケンスならばコントロールコードに戻す必要があり、処理時間が多くかかります。
その上 20H 以下のデータが大量に存在するとデータの収納効率が非常に悪ってしまうので、ディスクの容量を節約するためにも、これよりもっとな方法を考えた方がいいですね。
つづく
マシン語を使用したモノや BASIC のデータ領域/ワークエリア等を保存する方法として、まず最初に思いつくのはモニタモードでカセットテープに保存する方法ですが、これは速度も遅く信頼性も低いものでした。
「じゃあ、ディスクへの保存なら大丈夫だろう」と考えますが、最初期の Disk-BASIC には BSAVE / SAVEM 等のバイナリデータ保存用の命令はありませんでした。
話は横へそれますが
APPLE II は別として、国産 PC で FM-8 以前にディスクへのバイナリデータのロード/セーブが可能だったモノってありましたっけ?
そう考えると APPLE II って偉大です。
それはさておき
BASIC にバイナリデータのロード/セーブ命令が無いといってバイナリデータを扱えなかった訳ではありません。
BASIC に精通した真のプログラマは、プログラムを組んで問題を解決するものです。
まず最初に思いつくのは、メモリから PEEK() 関数を使用して読み込んだデータをシーケンシャルファイルに出力する方法ですが、これには問題があります。
BASIC のリファレンスマニュアルにはあまり詳しく書かれていないのですが、シーケンシャルファイルで扱えるデータは基本的にテキストデータだけ(',' (コンマ)を除く 20H から 7EH と 80H から FFH まで)です。
シーケンシャルファイル入力で使用する INPUT # 命令は INPUT 命令と違いコンソールからではなくファイルから入力を行います。 しかし、これはコンソールからの入力と同様にコントロールコードが有効になっているのです。
INPUT 命令では入力時に CR / ',' (コンマ) はデータの区切り/終了を意味しますが、同様に INPUT # 命令でも入力される文字列中に LF / CR / ',' (コンマ)が現れるとデータの区切りとみなされるため、データとしては無視されてしまいます。 また、00H も無視されてしまいます。
N-BASIC では、
00H(Null), 07H(Bell), 0AH(LineFeed), 0BH(Home), 0CH(Clear), 0DH(CarriageReturn), 1CH(CursorRight), 1DH(CursorLeft), 1EH(CursorUp), 1FH(CursorDown)
が、影響を受けるコードです。
そのため、影響を受けるコードを正常に読み込むには、例えば 00H → \@, 07H → \G, \ → \\ という具合にエスケープシーケンスを使用して 20H 以上のコードに変換しておく必要があります。
これだとデータを取りこぼすことなく読み込めますが、文字列変数に格納されたデータを1文字づつ取り出してチェックし、エスケープシーケンスならばコントロールコードに戻す必要があり、処理時間が多くかかります。
その上 20H 以下のデータが大量に存在するとデータの収納効率が非常に悪ってしまうので、ディスクの容量を節約するためにも、これよりもっとな方法を考えた方がいいですね。
つづく