Tatara

第26章
出力形式

TANRENは、1回のリンクで1つの出力ファイルを書き出します。この章では、そのファイルに何が入るか、ファイルの種類、そしてそれぞれの種類に合わせてプログラムをリンクする方法を説明します。MSX-DOS用の.COMのプログラム、ほかのアドレス用のイメージ、MSX-BASICのBLOAD用のファイル、ROMイメージの4つです。最後に、プログラムの大きさの限度について説明します。

26.1 TANRENが書き出すもの

出力ファイルには、プログラムのメモリのうち、内容のある最初のバイトから最後のバイトまでが入り、それ以外には何も入りません(24.1.1節)。/Bが付けるヘッダーを除いて、ファイルには、どのアドレスに置くものかは書かれていません。ファイルを読み込む側が、それを知っている必要があります。

表26.1に、4種類のファイルと、それぞれの作り方を示します。TANRENが標準で作るのは.COMだけです。ほかの種類では、出力ファイルの名前を/O:で指定するか、/Bで.binが付くようにします。

種類

リンクのしかた

読み込むもの

アドレス

.COM

そのまま。tanren main sub

名前を入力したときの MSX-DOS

0100h

そのままのイメージ

/P:。名前は/O:で指定します

ほかのプログラム

/P:のアドレス

.BIN

/Bと/P:

MSX-BASICのBLOAD

ヘッダーにあるアドレス

ROMイメージ

ソースにASEGと、4000hまたは8000hのORG。名前は/O:で指定します

カートリッジから読むMSX

4000hまたは8000h。MSXがヘッダーを探す場所です

表 26.1: 出力ファイルの種類。

26.2 .COMのプログラム

オプションを何も付けないと、TANRENは.COMのプログラムを作ります。MSX-DOSはこれを0100hに読み込んでそこから実行するので、0100h用にリンクされている必要があり、TANRENはそこからコードを置きます(24章)。

A:\>tanren main sub 
... 
2 modules, 16 records, ends at EOF. 
Wrote MAIN.COM, 0100-0125 (38 bytes), entry 0100.
 

.COMのプログラムには/P:を使わないでください。ファイルはやはり0100hに読み込まれ、中のアドレスがすべて合わなくなります。

26.3 ほかのアドレス用のイメージ

/P:を付けると、TANRENはプログラムをほかのアドレス用にリンクします。ファイルの種類は同じで、中身はバイトだけですが、そのアドレスでしか動かず、MSX-DOS以外の何かがそこに読み込む必要があります。たとえば、ファイルをメモリに読み込んで呼び出す、ほかのプログラムです。

次のモジュールは、MSXのBIOSの1文字を表示するルーチンCHPUT (BIOS.INC)で1行を表示するので、MSX-DOSなしで動きます。

; HELLOB.AS - prints a line with the BIOS, for BLOAD from BASIC. 
                include bios.inc 
                include ascii.inc 
                cseg 
start:          ld      hl,msg 
loop:           ld      a,(hl) 
                or      a 
                ret     z 
                push    hl 
                call    CHPUT 
                pop     hl 
                inc     hl 
                jr      loop 
                dseg 
msg:            db      'Hello from BLOAD.',CHR_CR,CHR_LF,0 
                end     start
 

C000h用にリンクすると、34バイトになります。

A:\>tanren /p:c000 hellob /o:hellor.bin 
... 
1 modules, 8 records, ends at EOF. 
Wrote HELLOR.BIN, C000-C021 (34 bytes), entry C000.
 

ファイルは21 0E C0、つまりld hl,msgで始まります。メッセージは、14バイトのコードのあとのC00Ehにあります。

26.4 BLOAD用のファイル: /B

MSX-BASICは、マシン語のファイルをBLOADで読み込みます。そのファイルは、どこに置くかを示す7バイトのBLOADヘッダーで始まっている必要があり、/Bを付けるとTANRENがそれを書きます。/Bを付けると、/O:で名前を指定しないとき、出力ファイルには.binが付きます。

A:\>tanren /b /p:c000 hellob 
... 
1 modules, 8 records, ends at EOF. 
Wrote HELLOB.BIN, C000-C021 (34 bytes), BLOAD header, entry C000.
 

要約行には、いつもと同じく、プログラムのアドレスと大きさが表示されます。ディスク上のファイルはヘッダーの分だけ7バイト多い41バイトです。HELLOB.BINのヘッダーを図26.1に示します。

アドレスはどれも2バイトで、Z80と同じく下位バイトが先です。ヘッダーのあとには、HELLOR.BINと同じ34バイトが続きます。

PIC

図 26.1: HELLOB.BINのBLOADヘッダーと、そこに入っている3つのアドレス。

MSX-BASICで,Rを付けてBLOADすると、ファイルを読み込んで開始アドレスを呼び出し、プログラムはRETでBASICに戻ります。

Ok 
bload"hellob.bin",r 
Hello from BLOAD. 
Ok
 

MSX-BASICが動いている間は、8000hより下のアドレスにはBASICのROMがあり、RAMは8000hから始まります。そのため、.BINのファイルは、その RAMの中の、BASICが使っているものを上書きしないアドレス用にリンクする必要があります。0100h用にリンクした.BINは、まったく読み込めません。完全な例は32章にあります。

26.5 エントリー・アドレス

エントリー・アドレスは、ENDの行に書いたアドレスです(12.6節)。複数のモジュールがそれを書いているときは、コマンド・ラインの順で最初のものが使われ、ほかは無視されます。E1.ASとE2.ASは、どちらも書いています。

; E1.AS - its END names e1start. 
                cseg 
e1start:        nop 
                ret 
                end     e1start
 
; E2.AS - its END names e2start, which is not its first byte. 
                cseg 
                nop 
e2start:        ret 
                end     e2start
 
A:\>tanren /b /p:c000 e1 e2 /o:e12.bin 
... 
Wrote E12.BIN, C000-C003 (4 bytes), BLOAD header, entry C000. 
A:\>tanren /b /p:c000 e2 e1 /o:e21.bin 
... 
Wrote E21.BIN, C000-C003 (4 bytes), BLOAD header, entry C001.
 

E1を先にするとエントリーはe1startのC000h、E2を先にするとe2startのC001hになります。

どのモジュールも書いていなければ、要約行にentryは表示されません。

; NOEND.AS - no address on its END line. 
                cseg 
                ld      a,1 
                ret 
                end
 
A:\>tanren noend 
... 
Wrote NOEND.COM, 0100-0102 (3 bytes).
 

BLOADヘッダーには必ずエントリー・アドレスがあるので、/Bを付けると、TANRENはプログラムの最初のアドレスを使い、要約行にもそれが表示されます。

A:\>tanren /b /p:c000 noend 
... 
Wrote NOEND.BIN, C000-C002 (3 bytes), BLOAD header, entry C000.
 

エントリー・アドレスが使われるのは、BLOADヘッダーの中だけです。MSX-DOSは、.COMのプログラムをいつも0100hから実行し(21.1節)、そのままのイメージもふつうは最初のアドレスから実行されます。そのため、/Bなしでは、エントリー・アドレスがそれ以外のとき、TANRENは警告を出し、ファイルはそのまま書き出します。

A:\>tanren e2 e1 /o:e21raw.bin 
... 
WARNING: E21RAW.BIN is entered at 0100, not at 0101. 
2 modules, 12 records, ends at EOF. 
Wrote E21RAW.BIN, 0100-0103 (4 bytes), entry 0101.
 

この警告は/Qを付けても表示されます。上のE21.BINのように、/Bを付けると警告は出ません。ヘッダーがBLOADに開始アドレスを伝えるからです。

26.6 ROMイメージ

16 KBのROMカートリッジは4000hから7FFFhにあり、MSXが起動するときに探すヘッダーで始まります。EXAMPLES\ROMのROM.ASは、その完全な例です(最初の数行のコメントは、ここでは短くしています)。

; ROM.AS - a 16 KB cartridge. 
 
                include bios.inc        ; INITXT, CHPUT, and the rest 
 
                aseg 
                org     4000h 
 
                db      "AB"            ; a cartridge, says the BIOS 
                dw      init            ; INIT: called at once 
                dw      0               ; STATEMENT: no CALL statements 
                dw      0               ; DEVICE: no device 
                dw      0               ; TEXT: no BASIC program in here 
                dw      0,0,0           ; reserved, and zero 
 
init:           call    INITXT          ; a text screen, from nothing 
                ld      hl,msg 
ini.lp:         ld      a,(hl) 
                or      a 
                jr      z,ini.end 
                push    hl 
                call    CHPUT 
                pop     hl 
                inc     hl 
                jr      ini.lp 
ini.end:        jr      ini.end         ; a cartridge has nowhere to go 
 
msg:            db      "Assembled by Tatara. Linked by TANREN.",13,10,0 
 
                org     7fffh           ; the last byte of the 16 KB... 
                db      0               ;   ...so that the file is all of it 
 
                end
 

コードはアブソリュート・セグメントにあり、ソースに書いたアドレスに置かれるので(24.5節)、/P:は要りません。

A:\>tanren rom /o:rom.rom 
... 
1 modules, 6 records, ends at EOF. 
Wrote ROM.ROM, 4000-7FFF (16384 bytes).
 

カートリッジのイメージは16,384バイトちょうどでなければならず、最後の 2行がそれを実現しています。TANRENは内容のある最初のバイトから最後のバイトまでを書き出すので、7FFFhに1バイト置くと、その前の空いた部分が 0としてファイルに入ります。この2行がないと、同じプログラムが77バイトのファイルになります。

A:\>tanren romshort /o:romshort.rom 
... 
Wrote ROMSHORT.ROM, 4000-404C (77 bytes).
 

最後にDSを置いても、そうはなりません。内容のある最後のバイトのあとにDSが確保したメモリは、ファイルに書き出されないからです(24.1.1節)。カートリッジについては33章でくわしく説明します。

26.7 プログラムの大きさの限度

TANRENは、MSX-DOSがプログラムに与えるメモリではなく、メモリ・マッパーの中でプログラムを組み立て、そこからファイルに書き出します。そのため、プログラムは、TANREN自身が動いているアドレスも含めて、0100hからFFFFhまでのアドレス空間全体を使えます。次のモジュールは、0100hに1バイト、それより 60 KB以上上にもう1バイトを置いています。

; BIG.AS - one byte at the start and one near the top of memory. 
                cseg 
                db      1 
                ds      0EF00h 
                db      2 
                end
 
A:\>tanren big 
... 
1 modules, 6 records, ends at EOF. 
Wrote BIG.COM, 0100-F001 (61186 bytes).
 

大きなプログラムには、そのイメージのための、そしてTANRENの表のための空いたメモリ・マッパーが十分に必要です。表の大きさは、モジュール、セグメント、名前の数など、プログラムによって変わります。メモリ・マッパーが足りなくなると、TANRENはERROR: out of mapper memory.と表示して止まります。

.COMのプログラムは、実行するときに、MSX-DOSが与えるメモリに収まらなければなりません。そのメモリはFFFFhよりかなり下で終わります。この限度はMSXとMSX-DOSによって決まり、リンカーによるものではないので、TANRENはこれを確認しません。

26.8 書き出すものがないとき

モジュールにDSしかないプログラムには、内容のあるバイトがないので、TANRENはファイルを書き出しません。

; EMPTY.AS - only DS: nothing to write. 
                dseg 
buffer:         ds      100 
                end
 
A:\>tanren empty 
... 
1 modules, 4 records, ends at EOF. 
Nothing to write: no module has any content.
 

これはエラーではありませんが、出力ファイルは作られず、以前のリンクで作った同じ名前のファイルは、そのまま残ります。

26.9 メッセージ

出力ファイルに関するメッセージを表26.2に示します。ERROR: the linked image would run past FFFFh.については24章で説明しています。

メッセージ

意味

ERROR: cannot create NAME

出力ファイルを作れません。たとえば、/o:nodir\x.comのように、そのディレクトリがないときです。名前は大文字で表示されます。

ERROR: cannot write the output file - the disk may be full.

ファイルは作られましたが、書き込みに失敗しました。

ERROR: out of mapper memory.

プログラムのイメージやTANRENの表のための場所が、メモリ・マッパーに残っていません。

WARNING: NAME is entered at XXXX, not at YYYY.

エラーではありません。/Bなしで書き出したファイルは最初のアドレスXXXXから実行されますが、ENDのアドレスはYYYY です。

Nothing to write: no module has any content.

エラーではありません。内容のあるバイトを持つモジュールがなく、ファイルは作られません。

表 26.2: 出力ファイルに関するメッセージ。