・pbsavea.pl version 0.5 PB-100用 wav ファイル作成ツール
昔のPCはプログラムをサウンドデータに変換してカセットテープに保存という手段を使っていました。
ポケコンもカセットI/Fを使ってSAVE/LOADをしていました。
そのサウンドデータに関する情報をまとめておきます。
データフォーマット
まず基本のデータフォーマットですが、いわゆる周波数変調の方式(FSK変調)で1/0を表現します。
有名どころはカンサスシティスタンダード(KCS)と呼ばれるもので、詳しくはwikiなどを参照して貰えばわかると思いますが、ざっくり言うと、2,400Hzの8サイクルが1で1,200Hzの4サイクルが0を現します。なので1秒間に300bitの情報を送れることになります(いわゆる300ボーってやつです)。
CASIOのPB-100はまさにこの仕様を使っています。
SHARP系は4,000Hz 8サイクル/2,000Hz 4サイクルなので500ボーです。(このフォーマット、名前あるのかな?)
wavファイル
そもそも扱うデータが2値なので、割と簡単にwavファイルが作れます。
KCSフォーマットのデータを作ろうとすると、サンプリング周波数は最小で4,800Hz(何故ならば矩形波の1周期データを表すのに最低2つのデータが必要だから)、振幅は最小で8bit必要です(1/0/-1の状態しかないので2bitで事足りますが)。
ちなみに通常使うサンプリング周波数は、8,000/22,050/44,100/48,000といったところなので、これに合わせたいところですが8,000Hzではうまく2,400Hzを表現できません。なので最小は22,050Hzになります(多分)。1/9にすれば2,450/1,225Hzになりますので。
振幅のビット数が8bitの場合は最大255/最小0/センター128なので、2,400Hzを表現する場合は1周期が"FF FF FF FF FF 00 00 00 00"となり、これを8回繰り返せば"1"になります。1,200Hzは"FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00"なので、これを4回繰り返すことで"0"となります。
SHARPの場合は8,000Hzがそのまま使えます。4,000Hzは"FF 00"を8回、2,000Hzは"FF FF 00 00"を4回繰り返せば良いことになります。
PB-100のフォーマット
(1)全体構成
(2)ヘッダ
(*1)種別:SAVE A形式の場合は"F"、SAVE形式は"D"。
(*2)行番号:プログラム先頭の行番号。BCDフォーマット。1234の場合は 0x34, 0x12。
(3)本体
(4) 1byteの構成
例えば 0x43 の場合は 0100 0011 なので、0 1100 0010 1 11 となります。
(5)プログラムの内部表現
例えば、
10 PRINT A
20 END
というプログラムを書いた場合、
10 00 | 行番号 | 2byte BCD リトルエンディアン |
A6 | 予約語:0xA6 | |
20 | A | 内部コード:0x20 |
FF | 行区切り | |
20 00 | 行番号 | |
AA | END | 予約語:0xAA |
FF | 行区切り |
という感じで記録されます。
なお、コロン ' : ' は通常の文字としては 0x5F ですが、ステートメントデリミタとして使われているときは 0xFE になります。
あと、SAVE A 形式で記録する場合はページ区切りコード 0xE0 が入ります。
(6) PB-100 のキャラクタコード
(*) スペースは 0x00
(7) PB-100 の予約語コード
x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | |
8x | SIN | COS | TAN | ASN | ACS | ATN | LOG | LN | EXP | SQR | INT | FRAC | ABS | SGN | RND | RAN# |
9x | LEN( | VAL( | MID( | KEY | CSR | TO | STEP | THEN | ||||||||
Ax | FOR | NEXT | GOTO | GOSUB | RETURN | IF | INPUT | MODE | STOP | END | ||||||
Bx | VAC | SET | PUT | GET | ||||||||||||
Cx | DEFM | SAVE | LOAD | VAR | LIST | RUN | CLEAR |
(*) 'LEN(', 'VAL(', 'MID(' はカッコを含めて予約語として定義されています。
SHARP系のフォーマット
そのうちまとめようと思います。。。