Tatara

第32章
MSX-BASICのBLOAD用のバイナリ

MSX-BASICは、マシン語のファイルをBLOADで読み込んで実行できます。この章では、A:\TATARA\EXAMPLES\BINARYにある例、BINARYを作ります。そのようなファイルを作ってBASICから実行し、そのあとで、BASICのメモリのどこにマシン語のファイルを安全に置けるかを見ます。

32.1 この例

BINARYは、1つのソースBEEP.ASと、そのBUILD.BATからなります。プログラムは1行を表示し、MSXのブザーを鳴らして、BASICに戻ります。これは.COMのプログラムではありません。BASICが実行するときにはMSX-DOSがないので、MSXのROMにあるルーチン、つまりBIOSを使って表示します。TANRENは、これをBLOADのヘッダー付きで書き出し(26.4節)、それによって.BINのファイルになります。

32.2 ソース

; BEEP.AS - a machine-code file for MSX BASIC. 
; 
; BLOAD"BEEP.BIN",R loads this and runs it. The seven bytes BASIC 
; reads first - FEh, the first address, the LAST address, and the 
; address to call - are written by TANREN when /B is given, and 
; nothing else makes a file a .BIN. 
; 
; ASEG and ORG: the code is at a fixed address and the linker moves 
; nothing. It has to be, because BASIC loads it where the header says 
; and does not relocate anything. 
; 
; There is no MSX-DOS here, so the printing is the BIOS. 
 
                include bios.inc        ; CHPUT, BEEP, and every other 
                                        ;   MAIN ROM entry 
                include ascii.inc       ; CHR_CR and CHR_LF 
 
                aseg 
                org     8000h           ; above BASIC in a 64 KB machine 
 
start:          ld      hl,msg 
loop:           ld      a,(hl) 
                or      a 
                jr      z,done 
                push    hl 
                call    CHPUT 
                pop     hl 
                inc     hl 
                jr      loop 
done:           call    BEEP 
                ret                     ; back to BASIC, which is waiting 
 
msg:            db      "Loaded by BLOAD, run from BASIC.",CHR_CR,CHR_LF,0 
 
                end     start           ; the address the header carries
 

32.3 作る

rem BUILD.BAT - EXAMPLE: BINARY 
rem 
rem A .BIN for MSX BASIC instead of a .COM for MSX-DOS. Two things 
rem make the difference: 
rem 
rem   ASEG and ORG   the code is at a fixed address, not relocatable 
rem   TANREN /B      the seven-byte BLOAD header goes in front of it 
rem 
rem The address BASIC calls is the one on the END line of the source. 
rem Without /B the same link writes the bytes and no header, which is 
rem what a ROM needs - see the ROM example. 
rem 
rem To run it, from BASIC:  BLOAD then the file name in quotes, ,R 
 
rem The headers are in A:\TATARA\INCLUDE and are not copied here. 
rem TATARA is rule 3 of the include search - see the DIRS example. 
rem CHANGE THE PATH BELOW if you put the tree somewhere else. 
 
set TATARA=a:\tatara\include 
 
echo === Assembling 
tatara /q beep.as beep.tro 
 
echo === Linking, with a BLOAD header 
tanren /q /b /o:beep.bin beep.tro 
 
echo === Done. BEEP.BIN is 7 bytes of header and the rest is code. 
 
set TATARA=
 
A:\TATARA\EXAMPLES\BINARY>build 
=== Assembling 
=== Linking, with a BLOAD header 
=== Done. BEEP.BIN is 7 bytes of header and the rest is code.
 

/Qなしで実行すると、TANRENの要約で書き出したものがわかります。

A:\TATARA\EXAMPLES\BINARY>tanren /b /o:beep.bin beep.tro 
... 
1 modules, 6 records, ends at EOF. 
Wrote BEEP.BIN, 8000-8035 (54 bytes), BLOAD header, entry 8000.
 

プログラムは54バイトで、ファイルは61バイトです。最初の7バイトがヘッダーです。

FE  00 80  35 80  00 80
 

FE、続いて最初のアドレス8000h、最後のアドレス8035h、呼び出すアドレス8000hで、どれも下位バイトが先です。そのあとにプログラムが続きます。21 13 80はld hl,msgで、メッセージは8013hにあります。

32.4 BASICから実行する

MSX-BASICで、例のディレクトリから、,Rを付けてBLOADすると、ファイルを読み込み、その開始アドレスを呼び出します。

Ok 
BLOAD"BEEP.BIN",R 
Loaded by BLOAD, run from BASIC. 
Ok
 

行のあとにブザーが鳴り、RETでBASICに戻って、BASICがOkと表示します。

32.5 ファイルを置ける場所

BASICが動いている間、8000hより下のアドレスにはBASICのROMとBIOSがあるので、BLOAD用のファイルは、その上のRAMに置く必要があります。しかし、BASICもそのRAMを使います。メモリの中のBASICのプログラムは 8000hのすぐ上から始まり、そのあとに変数が続きます。上の例がうまくいったのは、メモリにプログラムがなかったからです。プログラムがあると、同じファイルがそれを上書きします。

list 
10 PRINT "hello" 
Ok 
bload"beep.bin",r 
Loaded by BLOAD, run from BASIC. 
Ok 
list 
46974 INSTRMAXTRON 
25697 ed by BLOAD, run from BASIC.501WAIT_VPOKE=^KILLL<0MERGEeMAXO<>41933;+;(3:( 
...
 

マシン語はそれでも実行されて1行を表示しましたが、BASICのプログラムは消えています。LISTは、マシン語をプログラムのように読んで表示し、そのあとマシンは反応しなくなります。

CLEARを使うと、ファイルに必要なメモリからBASICを遠ざけられます。CLEAR 200,&HC000は、BASICに文字列用の200バイトを与え、さらにここで大事なことに、C000hから上のメモリを使わないようにBASICに伝えます。そうすれば、図32.1のように、C000hに置いたファイルは BASICの邪魔になりません。

PIC

図 32.1: MSX-BASICのメモリ。ファイルを8000hに置いた場合と、C000hに置いた場合。

BEEPC.ASは、BEEP.ASのORGを変えたものです。

                aseg 
                org     0C000h          ; above the CLEAR address
 
Ok 
clear 200,&hc000 
Ok 
bload"beepc.bin",r 
Loaded by BLOAD, run from BASIC. 
Ok
 

CLEARは、最初のBLOADの前、そしてBASICのプログラムを入力したり読み込んだりする前に実行してください。CLEARは変数も消すからです。マシン語を使うBASICのプログラムは、ふつうCLEARの行で始まり、そのあとで自分のファイルをBLOADします。マシン語が多いほど、CLEARに与えるアドレスを低くする必要があり、BASICに残るメモリは少なくなります。

32.6 試してみること

次のファイルは例には含まれていません。BUILD.BATと同じようにTATARAを設定して、例のディレクトリに作ってください。

32.6.1 コードをTANRENに置かせる

モジュールはASEGとORGを使わなくてもかまいません。BEEPR.ASは同じプログラムを標準のコード・セグメントに置いたもので、TANRENが/P:でそれを置きます(24.3節)。

; BEEPR.AS - the same code, relocatable: TANREN /P: places it. 
                include bios.inc 
                include ascii.inc 
                cseg 
start:          ld      hl,msg 
loop:           ld      a,(hl) 
                or      a 
                jr      z,done 
                push    hl 
                call    CHPUT 
                pop     hl 
                inc     hl 
                jr      loop 
done:           call    BEEP 
                ret 
msg:            db      "Relocated by TANREN /P:.",CHR_CR,CHR_LF,0 
                end     start
 
A:\TATARA\EXAMPLES\BINARY>tatara /q beepr.as beepr.tro 
A:\TATARA\EXAMPLES\BINARY>tanren /b /p:c000 /o:beepr.bin beepr.tro 
... 
Wrote BEEPR.BIN, C000-C02D (46 bytes), BLOAD header, entry C000.
 

こうすれば、同じソースをどのアドレス用にもリンクでき、複数のモジュールからなるプログラムを全体としてまとめて置けます。

32.6.2 USRで呼び出す

,Rなしでは、BLOADはファイルを読み込むだけです。DEFUSRがマシン語のルーチンのアドレスを示し、USRがそれを呼び出します。

Ok 
clear 200,&hc000 
Ok 
bload"beepr.bin" 
Ok 
defusr=&hc000 
Ok 
a=usr(0) 
Relocated by TANREN /P:. 
Ok
 

こうすれば、ルーチンを読み込み直さずに、プログラムが必要なだけ何度でも呼び出せます。

32.6.3 /Bを外す

/Bなしでリンクすると、ファイルは同じ54バイトで、ヘッダーはありません。

A:\TATARA\EXAMPLES\BINARY>tanren /o:beepraw.bin beep.tro 
... 
Wrote BEEPRAW.BIN, 8000-8035 (54 bytes), entry 8000.
 

FEで始まらないので、BLOADはこれを受け付けません。

Ok 
bload"beepraw.bin",r 
Bad file mode 
Ok