パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)
DUMPプログラム作成 (互換/(一般))
==========================================
どのプログラム言語でも、プログラム入門書なるものを見ると、本の最後の方に、一通りの文法を
学んだあとのおさらいとして、「DUMPプログラム」の作成が課題としてとりあげられています。
とりあえず、DUMPプログラムが一人で作成できれば、入門卒業として考えていいかもしれません。
DUMPプログラムを作成するには
・ファイルのオープン、クローズ、データの入出力
・キーボードからの入力と入力値の処理
・モニターへの表示、成型した出力(ゼロパッティングなど)
・条件判断と分岐
など、プログラム作成に必要な技法を一通り使います。DUMPプログラムが作成できれば、簡単なゲーム
などは容易に作れるでしょう。
というわけで、DUMPプログラムの作成をしてみましょう。ちなみに今回は、N88互換Basic
for Win
で作成しましたが、一般的なBasicでほとんど手直しなしで、移植できると思います。
N88互換Basic for Win では、field , get
といったランダムファイルアクセス系の命令が若干オリジナル
仕様(※ 旧BasicよりVisual Basicよりで、柔軟な仕様)になっていますが、今回のDumpプログラムでは
コードはそのままでたぶんO.K.だと思います。
もし、エラーが出るようであれば、お使いのBasicの文法仕様を確かめて、アレンジして下さい。
(※) 本家のN88BasicやF-Basicではランダムファイルのレコード長は256バイト固定ですが、
N88互換Basic for Winでは、レコード長は256バイト固定ではなく、FIELD# 命令で指定した変数の
バイト数の合計になります。
Basicにおけるランダムファイルの操作については「ファイルの操作(ランダムファイル)」をご参照下さい。
なお、ほぼ同様の機能を持ったDUMPプログラムをアセンブラで組んだものを、姉妹サイトにある
「DUMPプログラム作成 コード編」で解説しています。興味があればのぞいてみてください。
またVisual Basicでのバイナリファイルの入出力については「Binaryファイルの入出力(入力)」や
「Binaryファイルの入出力(書き込み)」をご参照下さい。
==========================================
1 DUMPプログラムの仕様について
プログラムの流れは以下の通りです
(1) ダンプしたいファイル名の入力
(2) コマンドの入力。コマンドは以下の通り。
D ダンプ開始 Q プログラム終了 C
バイナリーデータ検索
Cコマンドの検索で指定したデータは赤色で表示します。
Cコマンド指定例 &H5Eを検索データとして指定する場合
-C5E と記述します
(3) Dコマンドによるダンプ中にはサブコマンドが使えます。
サブコマンド 1 一時中断 2 再開
3 コマンド入力に戻る
下記は実行中の画面例です。Cコマンドで"0D"を指定しているので、0Dは赤色で表示されて
います。
2 プログラム概説
(1) 初期設定
コードに関しては、特に説明するところはありませんので、このプログラムで使っている変数に
について解説します。
50行目は、開発中の遺産です。ファイルをオープンするプログラム開発中に、プログラムのバグで
プログラムが終了すると、ファイルがクローズされない(オープンのまま)状態で残ってしまうことが
あります。そのため、プログラムの最初に、こんなおまじないを入れて開発したりしますが、その時
の残りです。削除して構いません。
60、70行目で変数の、宣言、初期化をしています。
b$ 読み込んだデータの一時保存用に使います
n ランダムファイル読み込み時のレコード番号
address ダンプ表示時のアドレス
frag 0 ダンプ中 1 ダンプ一時中断中
kan2 1
漢字の2バイト目のデータの可能性がある
10 ' File Dump Ver 0.0.2 for N88互換Basic 20 ' 30 '初期設定 40 on error goto 590 50 cls:close: 60 dim b$(17) 70 n=1:address=0:frag=0:kan2=0 80 print "File Dump ver0.0.1 for N88互換BASIC for Win"; 90 print " Written by Kasayan86" 100 print"***コマンド***" 110 print "D ダンプ開始 Q プログラム終了 C バイナリーデータ検索 指定したデータは赤色で表示" 120 print "Cコマンド指定例 &H5Eを検索データとして指定する場合 -C5E と記述して下さい" 130 print "ダンプ中のサブコマンド 1 一時中断 2 再開 3 コマンド入力に戻る" |
(2) ファイルオープン、コマンド入力
180行 ランダムファイルを開く時の、open の使い方です。(=ランダムモード)
ランダムモードでファイルを開くと、ファイルの好きな位置にアクセスして、データを取得することが
できます。
190行 c$=left$(cmnd$,1)
"-"に続けて入力されたコマンドをc$に抜き取ります
720行からはCコマンドの処理用サブルーチンです
720行 c1$=mid$(cmnd$,2,2)
"-"に続けて入力されたCコマンド文字列(=cmnd$)の2文字目から、2文字取り出して、c1$に入れます
例えば、"-C0D" と入力されたとすると、"0D"がc1$に代入されます。
730行 cv=val("&H"+c1$)
16進数の表記の文字列を数値変数に変換(関数val)して、数値変数cvに代入します。
140 ' 150 'ファイルオープン、コマンド入力処理 160 ' 170 input "File Name :", file$ 180 open file$ as #1 190 input "-",cmnd$: c$=left$(cmnd$,1) 200 if c$="Q" or c$="q" then goto 590 210 if c$="C" or c$="c" then gosub 720 220 if c$="D" or c$="d" then goto 270 230 goto 190 (途中省略) 590 close:end (途中省略) 690 ' 700 'バイナリデータ検索コマンド処理ルーチン 710 ' 720 c1$=mid$(cmnd$,2,2) 730 cv=val("&H"+c1$) 740 return |
(3) ダンプ表示
ダンプ表示部の大きな流れは以下の通りです。
(A) データ読み込み(16データづつ)
(B) バイナリー値表示
・アドレス表示
・16個のバイナリー値表示(Cコマンドで指定された値は赤色表示)
(C) アスキー部表示
(D) サブコマンド処理
まず、(A) データ読み込み(16データづつ)、(B) バイナリー値表示 のコードについて説明します。
270行 if eof(1) then close:goto130
eof( )関数は、ファイルエンドに到達すると-1(=True)を返しますので、その場合はclose処理をして130行に
飛びます。
ファイルが残っていれば0(=False)を返しますので、280行以下の処理を繰り返します。
ここは、if eof(1)=-1 then close:goto130
と書いても同じです。
290行、300行 16バイトづつ読み込みます
field #1,16 as a$
get #1,n
310行 print right$("0000"+hex$(address),4)+":
";
左にゼロパッティングしてアドレス表示します。ゼロパッティングの定番のコードの書き方です。
360行 b$(i)=mid$(a$,i,1)
a$から1バイトづつ取り出して、b$に代入します
380行 print right$("0"+hex$(asc(b$(i))),2);"
";
asc(b$(i)) --> b$のデータ(文字)のアスキーコード値(キャラクタコード)を取得し
hex$( ) --> ascは10進の数値変数として結果を返すので、16進数の文字列に変更します
right$("0" + ......, 2) -->
左にゼロパッティングして表示
240 ' 250 'ダンプ表示 260 ' 270 if eof(1) then close:goto130 'EOFになるまでダンプ継続 280 color 7 290 field #1,16 as a$ '16データづつ取得 -> a$ 300 get #1,n 310 print right$("0000"+hex$(address),4)+": "; 320 address=address+16 330 b$(17)=" " 340 'バイナリー値ダンプ表示 350 for i=1 to 16 360 b$(i)=mid$(a$,i,1) 370 if asc(b$(i))=cv then color 3 '検索データの色処理 380 print right$("0"+hex$(asc(b$(i))),2);" "; 390 color 7 400 next |
(C) アスキー部表示、(D) サブコマンド処理 の部分です。
440行 if i=1 and kan2=1 then b$(i)=" ":kan2=0:goto 490
先頭の1文字目のデータ(i=1)が、漢字の2バイト目(kan2=1)の可能性(すなわち、前の行の行末
=16文字目が、漢字の1バイト目の可能性)のあるときの処理です。このデータは、前の行のアスキー
表示部で処理済みなので、ここでは空白"
"を表示します。
480行 if ((asc(b$(i))>=&h80) and (asc(b$(i))<=&h9f))
or ((asc(b$(i))>=&hE0) and (asc(b$(i))<=&hFC)) then
gosub 630
漢字の1バイト目の可能性があるときは、630行の「2バイト文字処理サブルーチン」を呼びます
530行目〜570行目は、サブコマンドの処理です。
630行目以降は、2バイト文字処理サブルーチンです。
行末(=16バイト目)の場合は、
650 get #1,n+1 -->
次のレコード(16バイト)のデータ読み込み
660 nextb$=left$(a$,1):nextbb=asc(nextb$) -->
先頭の1バイトをnextb$に切り出し
670 if (nextbb>=&h40) and (nextbb<= &hFC) then kan2=1:b$(17)=nextb$
---->
2バイト文字の2バイト目だったら、行末アスキー表示の処理(b$(17)=nextb$)
410 'アスキー表示部処理 420 t$="" 430 for i=1 to 16 440 if i=1 and kan2=1 then b$(i)=" ":kan2=0:goto 490 450 if kan2=1 then kan2=0:goto 490 460 if asc(b$(i))<32 then b$(i)="." '表示できない文字処理 470 '2バイト文字処理 480 if ((asc(b$(i))>=&h80) and (asc(b$(i))<=&h9f)) or ((asc(b$(i))>=&hE0) and (asc(b$(i))<=&hFC)) then gosub 630 490 t$=t$+b$(i) 500 next 510 print ": ";t$+b$(17) 520 n=n+1 530 k$=inkey$ 540 if k$="1" then frag=1:print" 中断します。再開する時は2を、コマンド入力に戻る時は3を押して下さい" :goto 530 550 if k$="2" then frag=0 560 if k$="3" then frag=0: goto 190 570 if frag=1 then goto 530 580 goto 270 600 ' 610 '2バイト文字処理ルーチン 620 ' 630 if i=16 then goto 650 640 kan2=1: goto 680 650 get #1,n+1 660 nextb$=left$(a$,1):nextbb=asc(nextb$) 670 if (nextbb>=&h40) and (nextbb<= &hFC) then kan2=1:b$(17)=nextb$ 680 return |