Chapter 26
Output formats
TANREN writes one output file for each link. This chapter describes what is in that file, the kinds of file it can be, and how to link a program for each of them: a .COM program for MSX-DOS, an image for some other address, a file for MSX-BASIC’s BLOAD, and a ROM image. It ends with how large a program can be.
26.1 What TANREN writes
The output file holds the program’s memory from the first byte that has content to the last, and nothing else (section 24.1.1). The file does not say at which address it goes, except in the header that /B adds: whatever loads the file has to know.
Table 26.1 lists the four kinds of file, and how each one is made. Only .COM is TANREN’s default; for the others, the output file is named with /O:, or gets .bin with /B.
26.2 A .COM program
A .COM program is what TANREN makes without any option. MSX-DOS loads it at 0100h and starts it there, so it must be linked for 0100h, which is where TANREN starts the code (chapter 24):
A:\>tanren main sub ... 2 modules, 16 records, ends at EOF. Wrote MAIN.COM, 0100-0125 (38 bytes), entry 0100.
Do not use /P: for a .COM program. The file would still be loaded at 0100h, and every address in it would be wrong.
26.3 A raw image for another address
With /P:, TANREN links the program for another address. The file is the same kind of file, the bytes and nothing else, but it only works at that address, and something other than MSX-DOS has to load it there: another program, for example, that reads the file into memory and calls it.
This module prints a line with CHPUT, the routine of the MSX’s BIOS that prints a character (BIOS.INC), so that it works without 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
Linked for C000h, it is 34 bytes:
A:\>tanren /p:c000 hellob /o:hellor.bin ... 1 modules, 8 records, ends at EOF. Wrote HELLOR.BIN, C000-C021 (34 bytes), entry C000.
The file starts with 21 0E C0, ld hl,msg: the message is at C00Eh, after the fourteen bytes of code.
26.4 A file for BLOAD: /B
MSX-BASIC loads a machine-code file with BLOAD. The file must start with a seven-byte BLOAD header that says where it goes, and /B makes TANREN write one. With /B, the output file gets .bin when it is not named with /O::
A:\>tanren /b /p:c000 hellob ... 1 modules, 8 records, ends at EOF. Wrote HELLOB.BIN, C000-C021 (34 bytes), BLOAD header, entry C000.
The summary line gives the addresses and the size of the program, as always. The file on the disk is 41 bytes, seven more, because of the header. Figure 26.1 shows the header of HELLOB.BIN:
- FE, which marks a machine-code file;
- the first address of the program, C000h;
- the address of its last byte, C021h, not the address after it;
- the address where it starts, the entry address, C000h (section 26.5).
Each address is two bytes, the low byte first, as the Z80 keeps them. After the header come the same 34 bytes as in HELLOR.BIN.
In MSX-BASIC, BLOAD with ,R loads the file and calls its start address, and the program returns to BASIC with RET:
Ok bload"hellob.bin",r Hello from BLOAD. Ok
While MSX-BASIC runs, the addresses below 8000h hold its ROM, and the RAM starts at 8000h, so a .BIN file has to be linked for an address in that RAM, where it does not overwrite what BASIC is using. A .BIN linked for 0100h cannot be loaded at all. Chapter 32 is a complete example.
26.5 The entry address
The entry address is the address named on an END line (section 12.6). When more than one module names one, the first in command-line order counts, and the others are ignored. E1.AS and E2.AS each name one:
; 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.
With E1 first, the entry is e1start, at C000h; with E2 first, it is e2start, at C001h.
When no module names one, the summary line has no 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).
A BLOAD header always has an entry address, so with /B TANREN uses the first address of the program, and the summary line says so:
A:\>tanren /b /p:c000 noend ... Wrote NOEND.BIN, C000-C002 (3 bytes), BLOAD header, entry C000.
The entry address is used only in the BLOAD header. MSX-DOS always starts a .COM program at 0100h (section 21.1), and a raw image is usually entered at its first address too. Without /B, TANREN therefore warns when the entry address is anything else, and still writes the file:
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.
The warning is printed even with /Q. With /B there is none, as E21.BIN above shows: the header tells BLOAD where to start.
26.6 A ROM image
A ROM cartridge of 16 KB sits at 4000h to 7FFFh, and starts with a header that the MSX looks for when it starts. ROM.AS, in EXAMPLES\ROM, is a complete one (its first lines, a comment, are shortened here):
; 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
The code is in the absolute segment, at the addresses written in the source (section 24.5), so no /P: is needed:
A:\>tanren rom /o:rom.rom ... 1 modules, 6 records, ends at EOF. Wrote ROM.ROM, 4000-7FFF (16384 bytes).
A cartridge image has to be the full 16,384 bytes, and the last two lines make it so: TANREN writes everything from the first byte with content to the last, and a single byte at 7FFFh makes the gap before it part of the file, as zeros. Without those two lines, the same program makes a file of 77 bytes:
A:\>tanren romshort /o:romshort.rom ... Wrote ROMSHORT.ROM, 4000-404C (77 bytes).
A DS at the end would not do it, because the memory a DS reserves after the last byte of content is not written to the file (section 24.1.1). Chapter 33 describes the cartridge in full.
26.7 How large a program can be
TANREN builds the program in the memory mapper, not in the memory that MSX-DOS gives to programs, and writes it to the file from there. A program can therefore use the whole address space, from 0100h to FFFFh, including the addresses where TANREN itself is running. This module has a byte at 0100h and another more than 60 KB above it:
; 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).
A large program needs enough free mapper memory for its image, as well as for TANREN’s tables, whose size depends on the program: how many modules, segments and names it has. When the mapper runs out, TANREN stops with ERROR: out of mapper memory.
A .COM program still has to fit in the memory MSX-DOS gives it when it runs, which ends well below FFFFh. TANREN does not check this: the limit depends on the MSX and on MSX-DOS, not on the linker.
26.8 When there is nothing to write
A program whose modules hold only DS has no byte with content, and TANREN writes no file:
; 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.
This is not an error, but no output file is made, and one of the same name from an earlier link is left as it was.
26.9 Messages
Table 26.2 lists the messages about the output file. ERROR: the linked image would run past FFFFh. is described in chapter 24.