PC-6001用互換BASIC

PC-6001用の互換BASICを書いてみました。だいぶ形にはなってきましたが、まだまだバグや不具合があると思います。気付いた点があれば教えてもらえると幸いです。

(2017.2.17 Ver.0.6.1を公開しました)


目次


使い方

詳細については各エミュレータのマニュアルなどを参照してください。

  1. 互換BASIC Ver.0.6.1をダウンロードして展開します。
  2. 展開した中にあるBASICROM.60をエミュレータの指定するところに置きます (mkIIのモード2として動かしたい場合はBASICROM.62)。実機から吸い出したファイルが既にある場合、本物を上書きしてしまわないよう注意してください。
  3. 機種は「PC-6001」もしくは「PC-6001mkII」を選択します。
  4. エミュレータにCRCチェック機能がある場合は無効にします。
  5. CGROM60.60 (mkIIとして動かす場合はCGROM60.62) が無い場合は次節を参照してください。

CGROMファイルについて

エミュレータを動かすためには、BASICROM.60の他にCGROM60.60というフォントファイルが必要です (機種をPC-6001と指定した場合)。これについては同梱していませんので、利用者が各自用意する必要があります。方法としては、以下の四つがあると思います。

(※mkIIの場合はCGROM60.62が必要です。実機から吸い出せない場合は、CGROM60.60を二つ連結させてサイズを倍にしたものを作成するのが手っ取り早いかと思います)

1.実機から吸い出す

これができれば一番です。詳しくは、Hashiさんのサイトの「BIOS吸出し手順」などを参照してください。

2.公開されているフォントファイルを使う

エミュレータ上で使えるように一から制作された独自のフォントがいくつか公開されています。ダウンロードして展開するだけ!ありがたや。

3.自分で打ち込む

ばんばんさんが制作されたCGROM交換ツール (p6font.exe) を使うと、自分でCGROMファイルを作成できます。写真などを見ながら本物のフォントを再現するのも良いですし、自分ならではのフォントを作成して使うのも面白いかもしれません。

4.他の形式のフォントファイルから変換する

BDF形式のビットマップフォントを元にしてCGROM60.60形式のファイルを生成するプログラムを同梱しました。PC-6001のフォントは8×12ドットサイズですが、元のフォントがそれより小さい場合はそのまま、大きい場合は適当に縮小します。また、トランプマークが含まれない場合は▲▼★◆で代用するようにしました。単純な変換なので読みにくくなる字もあると思いますが、うまくフォントを選べばとりあえずの使用には耐えるのではないかと思います。TTFやPCFなど他形式のフォントファイルを使いたい場合は、otf2bdfやpcf2bdfといったBDFへの変換プログラムを併用すればうまくいくかもしれません。

使い方は、コマンドラインより

bdf2cgrom [-n] [-ascii] fontfile.bdf outfile

のように打ち込みます。出力ファイルは確認なく上書きするので注意してください。オプションとして、-8や-10などとすると、縦のサイズが8ドットや10ドットになるように変換を行います。うまく加工すればmkII以降用のCGROMファイルとして使用できるのではないかと思います。1バイト文字集合のフォントの場合は-asciiオプションで変換できますが、仮名文字やグラフィック文字などは空白となります。Windows以外のOSでは、src/bdf2cgrom.cをコンパイルして使ってください。

※変換したフォントファイルの扱いには十分注意してください。再配布はもちろん、他OSでの使用や変換自体を制限するライセンスのフォントもあるようです。

k8x12Lの画像
k8x12Lを変換した例

美咲フォントの画像
美咲フォントの明朝体を変換した例

東雲フォントの画像
東雲フォントの12ドット丸文字を変換した例


P6用のゲームを公開しているサイト

かつて販売されたり雑誌に掲載された自作ゲームを公開されている方、作者の許可を得て公開されている方、新作ゲームを公開されている方などがいらっしゃいます。P6を持っていない、エミュレータで初めてP6に触れてみたけれど何をしたらいいかわからない、という方は、まずこの辺りから試してみるといいかもしれません。感謝しつつ遊ばせてもらいましょう。


旧バージョン


ROM内ルーチン

以下のルーチンのアドレスや入出力レジスタなどをN60-BASICと揃えました。実機のROMは見ないことにしているので、各ルーチンの仕様については参考文献の記述に全面的に頼っています。また、ワークエリアについてはなるべく合わせるようにしていますが、完全互換は恐らく難しいのではないかと思います。実装しているワークについてはソースリストを参照してください。

アドレス概要 入力出力破壊 詳細
0000h ブート
0008h パラメータチェック HL HL A,CY,Z コール命令の次のアドレスのデータと(HL)を比較し、合えば0010hへ
0010h スペースをスキップして1文字読む HL A,HL,CY,Z F HL=先頭アドレス-1 A=データ Aが00hか3AhならZ=1 Aが30h〜39hならCY=1
0018h フック - - - FFDBhにジャンプ
0020h HL,DE比較 HL,DE CY,Z AF
0028h 実数の符合チェック (FA66h)〜(FF6Ah) A,Z AF 0ならZ=1,A=0 正ならZ=0,A=1 負ならZ=0,A=FFh
0038h フック - - - FFE1hにジャンプ
0390h 文字列データ - - - "OK"+CRLF
0442h ダイレクトコマンドモード
0741h 実数→整数 (FF66h)〜(FF6Ah)DE AF,B,HL USR関数で引数をレジスタに入れるのに使用。破壊レジスタについては資料無し
0D16h 整数→実数 AB (FF66h)〜(FF6Ah) AF,BC,HL USR関数で結果をBASICに返すのに使用。破壊レジスタについては資料無し
0DE3h 式解析 HL A,E,HL F,BC,D HLを+1した後、HLを開始アドレスとする中間言語による式を解析して、符号無し1バイト整数をAとEに返す。破壊レジスタについては資料無し
0DE4h 式解析 HL A,E,HL F,BC,D HLを開始アドレスとする中間言語による式を解析して、符号無し1バイト整数をAとEに返す。破壊レジスタについては資料無し
0E78h サブCPU入力 - A F 破壊レジスタについては資料無し
0E8Fh サブCPU出力 A - - 破壊レジスタについては資料無し
0EB0h キー入力割り込み処理 - - - GRAPH、STOP、ファンクションキー等の処理
0EB5h キー入力割り込み処理 - - - 一般キーの処理
0F74h タイマ割り込み処理 - - - TIMEカウント、カーソル点滅、PLAYの演奏を行う。動作を追加するには、新しい割り込みルーチンの最後をJP 0F74hとし、先頭アドレスをFA06h-FA07hに書けば良い
0FBCh キー入力 - A,Z F 入力が無ければZ=1
0FC4h キー入力 - A F 入力があるまでカーソルを点滅させながら待つ
103Ah キー入力 - A,Z F 入力が無ければZ=1。ファンクションキーのデコードを行わない
1058h キーバッファクリア - - HL
1061h ゲームキー入力 - A F
7 スペース
6 0
5
4
3
2
1 STOP
0 SHIFT
1075h 文字表示 A - - A=文字
10AAh 文字表示 A - AF,HL A=文字 コントロールコード処理は行わない。破壊レジスタについては資料無し
116Dh 文字表示位置設定 HL - - H=X+1 L=Y+1
11B8h Y座標→左端のVRAMアドレス L DE - L=Y+1 テキストモードにおけるアドレス
11CDh キャラクタ座標→VRAMアドレスHL HL - H=X+1 L=Y+1 テキストモードにおけるアドレス
11DAh 1行消去 DE - - DE=左端のVRAMアドレス グラフィック画面で使う時もテキストモードにおけるアドレスを入力
1257h 文字表示 A,HL- - A=文字 H=X+1 L=Y+1 位置移動とコントロールコード処理は行わない
1260h スクロール HL - AF H=Y上+1 L=Y下+1 指定は行単位。グラフィック画面でも使用可
12A9h 逆スクロール HL - AF H=Y下+1 L=Y上+1 指定は行単位。グラフィック画面でも使用可
1390h 画面モード設定 A - AF,DEA=モード-1
13EDh 表示画面設定 A - AF A=ページ-1
140Ch 使用画面設定 A - - A=ページ-1
1478h VRAMアドレス変換 HL HL - キャラクタモードでのアドレスをグラフィックモードでのアドレスに変換
14A0h CGROMアドレス計算 A DE -
15C0h アトリビュートセットA A F カラーコードを入れてコールすると(FEACh)にアトリビュートをセットする。スクリーンモード2ではそのままの値
1A4Fh 平仮名→片仮名変換 A A F
1A61h テープ入力開始 - - - リレーONも行う
1A70h テープ1バイト入力 - A F リードエラーならZ=0
1AAAh テープ入力終了 - - - リレーOFFも行う
1AB8h テープ出力開始 - - - リレーONも行う
1ACCh テープ1バイト出力 A - -
1AEDh テープ出力READYチェック - Z AF,B Z=0なら準備OK。破壊レジスタについては資料無し
1B06h テープ出力終了 - - - リレーOFFも行う
1B49h テープ用リレーOFF - - AF,B 破壊レジスタについては資料無し
1B4Bh テープ用リレーON - - AF,B 破壊レジスタについては資料無し
1B54h ポートB0h出力 A,B - AF A=出力データ B=変更ビットを1にしたもの
1B60h PLAY停止サブ - - - ユーザは1BB3hを使うべきとされる。詳細不明
1BB3h PLAY停止 - - -
1BBEh PSG出力 A,E D - A=レジスタ E=出力値 D=元の値
1BC5h PSG出力 A,E - - A=レジスタ E=出力値
1BCDh ベル - - AF,BC,E
1CA6h ジョイスティック入力A A F 入力=1or2
出力
7 0
6 0
5 (トリガ2)
4 トリガ1
3
2
1
0
1DBBh COLOR第3パラメータ実行 A - AF,BC,DE A=1or2
1DFBh CLS - - AF,DE
1EB3h PLAY HL,Z=0 HL AF,BC,DE 入力=PLAY文字列先頭アドレス(ダブルクォーテーションマークのアドレス) 出力=文字列最後の次のアドレス(通常はコロンか00hのあるアドレス)
2030h 音階データ - - - mkII用のアドレス
204Bh 音階データ - - - O1C〜O1B各音に対応するPSGレジスタ0,1のデータ
2539h CLOADヘッダ読み取り - (FED1h)〜(FED6h) AF,B,DE D3h×10個を確認した後、(FED1h)以降にファイル名を格納する。破壊レジスタについては資料無し
254Eh テープ連続データチェック DE - AF,B テープを読み、データEがD個連続するまで読み飛ばす。破壊レジスタについては資料無し
2576h 文字列データ - - - "Found:"
2583h ファイル名表示 HL - AF,BC,DE,HL (HL)からの文字列及び(FED1h)からのファイル名を表示。破壊レジスタについては資料無し
259Ah INPUT#-1開始 - - AF,B1A61hコール後、9Chが6個連続するまで読み飛ばす。破壊レジスタについては資料無し
25A8h PRINT#-1開始 - - A,B 1AB8hコール後、9Chを6個出力。破壊レジスタについては資料無し
25E5h ウェイト - - AF,BC 約3.5秒待つ。破壊レジスタについては資料無し
26C7h デバイス1文字出力 A,(FA58h) - AF (FA58h)=出力デバイス(0=CRT 1=プリンタ 2=RS-232C 80h〜FFh=テープ)
2739h デバイスCRLF出力 (FA58h) - AF 同上
274Dh STOP/ESCチェック - - AF ESCが押されれば一時停止、STOPが押されればBreak
28F9h 1行入力 - HL,CYAF,BC,DE HL=FED9h(入力バッファ-1) STOP入力時はCY=1
2D13h グラフィック座標セット BC,DE,Z BC=(FDAEh)〜(FDAFh)=(FEADh)〜(FEAEh)=X DE=(FDB0h)〜(FDB1h)=(FEAFh)〜(FEB0h)=Y F,BC,DE ワークエリアへのセット。Z=1なら相対座標
2D47h PSET BC,DE,(FEACh) - AF,BC,DE BC=X DE=Y (FEACh)=アトリビュート
2DE4h LINE BF BC,DE,(FEADh)〜(FEAEh),(FEAFh)〜(FEB0h),(FEACh) - AF,BC,DE BC=X1 DE=Y1 (FEADh)〜(FEAEh)=X2 (FEAFh)〜(FEB0h)=Y2 (FEACh)=アトリビュート
2E1Fh LINE 同上 - AF 同上
2E35h LINE B 同上 - AF,BC,DE 同上
2EFAh PAINT BC,DE,(FEACh),(FEC5h),(FEC6h) - AF,BC,DE BC=X DE=Y (FEACh)=領域色アトリビュート (FEC5h)=境界色アトリビュート (FEC6h)=境界色カラーコード
30CFh デバイス文字列出力 HL,(FA58h) - AF,BC,DE,HL 00hかダブルクォーテーションマークまで出力。HL=文字列アドレス (FA58h)=出力デバイス(0=CRT 1=プリンタ 2=RS-232C 80h〜FFh=テープ)
310Fh ガベージコレクション - - AF,BC,DE,HL
3AA1h 10進表示 HL - AF,BC,DE,HL 符号無し
3AA5h 整数→文字列HL HL AF,BC,DE 符合無し,HLに文字列アドレスが入る
3AACh 実数→文字列(FF66h)〜(FF6Ah) HL AF,BC,DE HLに文字列アドレスが入る
3BAFh 乱数生成 - (FF66h)〜(FF6Ah) AF,BC,DE,HL 乱数列を一つ進めて実数で格納する

以下のBASIC命令についてのアドレスもN60-BASICと揃えてあります。パラメータ文字列のアドレスをHLに入れてコールすると、各命令と同じ処理を行います。

アドレス命令
0781h RUN
07E0h DATA
07E2h REM
087Ah LPRINT
087Eh PRINT
1D9Bh COLOR
1E04h SCREEN

おまけ:ターミナル用P6エミュレータ

ターミナル上で動くPC-6001エミュレータを書いてみたので、おまけとして紹介します。どうやっても再現度に限界のあるアプローチですが、その分手軽に扱える面もあるのではないかと。

ターミナル用P6エミュレータの画像
ターミナル上でP6エミュレータ

オリオンの画像 クエストの画像
簡易グラフィック表示を実装

特徴

使い方の詳細については、同梱のreadme.htmlをご覧ください。

2015.10.13バージョン


おまけ:戦士のカートリッジmkII用プログラム

戦士のカートリッジmkII (新ベルーガカートリッジ) 用の、CLOADルーチンを上書きしてフラッシュROMからテープイメージを読み込めるようにするプログラムです。

  1. Ctrl+A〜Ctrl+Xで起動できるROMブロックにselector.binもしくはselector2.binを書き込みます。
  2. 読み込みたいテープイメージをct8k.exeで8KBずつに分割して、どこかのブロックから順番に(隙間を空けずに)書き込みます。
  3. Ctrlで起動します。
  4. 読み出したい先頭ブロックをカーソルキーで選択し、スペースキーを押します。
  5. BASICが起動したら、CLOADなど通常通りの手順で動かしてください。

※BASIC ROMを裏RAMにコピーしてパッチを当てる方式です。
※ROM内ルーチン (1A61h,1A70h) を使用せずにロードを行うプログラム (ドアドアmkIIやオホーツクに消ゆなど) には使えません。
※ワークエリアとしてRS-232C用バッファを使うので、RS-232Cとの併用並びに同じ領域を利用するプログラムでの利用はできません。
※SRのモード6では使えません。


参考文献


トップ > 雑多なもの > PC-6001用互換BASIC