Using External Programs

Full BASIC assumes the program has been compiled when the execution starts. Thus no program that rewrites itself can be executed.
We free Decimal BASIC from this restriction by writing out a program to a file and executing a CHAIN or EXECUTE statement.

Example.
A program that plots a graph of a function that is entered in syntax of BASIC.

100 REM Enter a function of x to plot the graph within the range of -8 to 8.
110 DATA "SET POINT STYLE 1"
120 DATA "SET WINDOW -8,8,-8,8"
130 DATA "DRAW GRID"
140 DATA "FOR x=-8 TO 8 STEP 0.0004"
150 DATA "   WHEN EXCEPTION IN"
160 DATA "      PLOT POINTS:x,f(x)"
170 DATA "   USE"
180 DATA "   END WHEN"
190 DATA "NEXT x"
200 DATA "FILE DELETE ""temp.bas"""       ! clear away 
210 DATA "END"
220 INPUT PROMPT "f(x)=":s$          ! Enter the expression of the function
230 OPEN #1:NAME "temp.bas"          ! Write out a BASIC program
240 ERASE #1
250 PRINT #1:"DEF f(x)=";s$
260 DO
270    READ IF MISSING THEN EXIT DO: s$
280    PRINT #1:s$
290 LOOP
300 CLOSE #1
310 CHAIN "temp.bas"               ! Execute the program 
320 END

Deleting the file "temp.bas" is a job of temp.bas, so, if temp.bas has syntax error and is not exccuted, the file "temp.bas" remains not to be removed. Thus we should run the program again until no syntax error is reported.
If this is the problem, use an EXECUTE statement but a CHAIN statment, write a FILE DELETE statement following the EXECUTE statment.

100 REM Enter a function of x to plot the graph within the range of -8 to 8.
110 DATA "SET POINT STYLE 1"
120 DATA "SET WINDOW -8,8,-8,8"
130 DATA "DRAW GRID"
140 DATA "FOR x=-8 TO 8 STEP 0.0004"
150 DATA "   WHEN EXCEPTION IN"
160 DATA "      PLOT POINTS:x,f(x)"
170 DATA "   USE"
180 DATA "   END WHEN"
190 DATA "NEXT x"
200 DATA "GSAVE ""TEMP.BMP"",""4bit""" ! save the graph into a file to finish
210 DATA "END"
220 INPUT PROMPT "f(x)=":s$          ! Enter the expression of the function
230 OPEN #1:NAME "temp.bas"          ! Write out a BASIC program
240 ERASE #1
250 PRINT #1:"DEF f(x)=";s$
260 DO
270    READ IF MISSING THEN EXIT DO: s$
280    PRINT #1:s$
290 LOOP
300 CLOSE #1
310 EXECUTE "temp.bas"               ! Execute the wriiten out program 
320 FILE DELETE "temp.bas"           ! clear away
330 WHEN EXCEPTION IN
340    GLOAD "TEMP.BMP"              ! recieve the result
350    FILE DELETE "TEMP.BMP"        ! clear away
360 USE
370 END WHEN
380 END


In practical use, the written out program elements should be held on a file.

2. Hand over data to another program

An EXECUTE statment can be used for launching an EXE-file. The parameters for the EXE-file can be designated on the WITH clause of the EXECUTE statement.

Example.
Write out temp.txt and open it with Notepad.

10 DATA "Hello"
20 OPEN #1:NAME "A:temp.txt" 
30 ERASE #1
40 READ  s$
50 PRINT #1:s$
60 CLOSE #1
70 EXECUTE "NOTEPAD.EXE" WITH ("A:temp.txt")   
80 END



When the extension ".txt" is associated with Notepad, the line 70 in the above can be replaces with the following.
70 EXECUTE "A:temp.txt"
In general, we can entrust a job to some program that can has a file name as a run paramater.
For example, if another BASIC than Decimal BASIC can deal with a job, with which Decimal BASIC cannot deals, we make a program written in the syntax of that BASIC, write out it into a file and hand it to that BASIC.
If some program sends a mail on launched with a name of the file that contains the an addressee and contents ing name, we can send a mail in an execution of a BASIC program.

3. Make binary files to hand over them to another program

When we write
OPTION CHARACTER BYTE
at the beginning of a program, all bytes becomes characters, so that for any integer from 0 to 255
PRINT #1:chr$(n);
appends a byte at the tail of the file. Note that a semicolon is needed at the end.

That is to say, if we know the format of the files, we can make any binary file.
For example, if we know the format of the sound files, we can compose a sound file so that we play the file. In general, if a program transacts a file indicated as a run-parameter, we can do any task by making a file of demanded format.

Note that the scope of OPTION CHARACTER BYTE is the program unit. If a program has external functions or external subprograms, they may have to have OPTION CHARACTER BYTE.

Generate a WAV file to play

 WAVファイルフォーマットに関する情報は, WAV ファイルフォーマット があります。
十進BASIC掲示板に実際の作例が掲載されました。たかしさんからの情報ですが,実際の作者は別の方のようです。
なお,プログラムのはじめに
OPTION CHARACTER BYTE
を書いておけば,オプションメニューでの前操作は不要です。

REM testwave.bas 十進BASICによる音声ファイル生成プログラム 
REM (L:1KHz -10dB 正弦波、R: 振幅 -10dB {パワーは-11.76dB} 白色雑音)
REM chr$関数の引数として全ての1バイト整数が許される様に、オプションメニューの
REM 「互換性」「動作」で「文字列処理の単位」を「バイト」に設定して実行すること
LET d=10 !継続時間(秒)
LET f0=1000 !正弦波周波数(Hz)
LET db=-10 !生成波形の最大値(±32767を0dBとする)
LET fs=44100 !標本化周波数(Hz)
LET bps=fs*4 !1秒当りのデータ量(ステレオ16ビット量子化)
LET dsize=d*fs*4 !オーディオデータサイズ
LET fsize=dsize+36 !ファイルサイズ(先頭8Bを除く)
LET fmtsize=16 !フォーマットサイズ
LET channel=2^17+1 !ステレオPCMデータの指定
LET reso=2^20+4 !16ビットの指定
LET a=10^(db/20)
OPEN #6 : NAME "test.wav" !ファイルを開き、この名前のファイルが
ERASE #6 !既に存在していた場合には上書きを指定
LET t0=TIME
PRINT #6 : "RIFF"; !以下、wavファイルのヘッダーを作成
CALL out4(fsize) !
PRINT #6 : "WAVEfmt "; !
CALL out4(fmtsize) !
CALL out4(channel) !
CALL out4(fs) !
CALL out4(bps) !
CALL out4(reso) !
PRINT #6 : "data"; !
CALL out4(dsize) !ここまでがヘッダー用の出力
LET al=a*32767 !左チャネル係数
LET ar=a*65535 !右チャネル係数
LET k=f0/fs*PI*2 !引数の刻み
LET audio$="" !オーディオデータバッファを初期化
LET count=0 !カウンタをリセット
FOR i=1 TO d*fs
   LET lch=INT(SIN(i*k)*al+0.5) !左チャネルは1kHz正弦波
   IF lch<0 THEN LET lch=lch+65536 !負の数は補数表現
   LET rch=INT((RND-0.5)*ar+0.5) !右チャネルは白色雑音
   IF rch<0 THEN LET rch=rch+65536 !負の数は補数表現
   LET audio$=audio$&CHR$(MOD(lch,256))&CHR$(INT(lch/256))&CHR$(MOD(rch,256))&CHR$(INT(rch/256))
   LET count=count+1
   IF count=64 THEN !バッファデータが所定の長さ(64サンプル256Bがほぼ最適)に達したら
      PRINT #6 : audio$; !データをファイルに出力して
      LET audio$="" !バッファを初期化し
      LET count=0 !カウンタをリセット
   END IF 
NEXT i
PRINT #6 : audio$; !バッファに残ったデータを出力して
CLOSE #6 !ファイルを閉じる
PRINT "elapsed time = ";TIME-t0;"seconds"
SUB out4(i4) !4バイト整数の出力(little endian)
   LET j4=i4
   FOR m=0 TO 3
      PRINT #6 : CHR$(MOD(j4,256));
      LET j4=INT(j4/256)
   NEXT m
END SUB
END 


なお,Windows版十進BASICでは,この後,

PLAYSOUND "test.wav"
END

を実行すれば,音が聞けます。

4.General Notice

ファイル名を引数として指定して起動したとき,それをどう処理するかは,相手のEXEファイル次第です。


<参照>ver 5.4.0でのCHAIN文,EXECUTE文の動作の変更


戻る