Tatara

Chapter 14
The include files

Tatara comes with nine include files of names for the MSX: the MSX-DOS2 functions and error codes, the BIOS and SUB ROM entry points, the hooks, the system work area, the I/O ports, the extended BIOS and the control codes. Chapter 3 put them in A:\TATARA\INCLUDE, and chapter 13 showed how INCLUDE finds them. This chapter describes what is in them and what to know before including each one. Appendix K summarises each file and names the books that describe what is in it.

14.1 What the files hold

Table 14.1 lists the nine files. Together they hold 903 names and one macro, system, which is in MSXDOS.INC.

File

What it holds

Names
ASCII.INC

the control codes

37
BIOS.INC

the MAIN ROM entry points

92
ERRORS.INC

the MSX-DOS and MSX-DOS2 error codes

76
EXTBIO.INC

the extended BIOS, and the MSX-MUSIC FM BIOS

85
HOOKS.INC

the hooks

117
MSXDOS.INC

the MSX-DOS function numbers, and the system macro

93
PORTS.INC

the I/O ports

56
SUBROM.INC

the SUB ROM entry points

36
WORKAREA.INC

the system work area

311
Table 14.1: The include files.

The names are the ones the MSX documentation uses, as the MSX Datapack spells them, so a name in your source is the same as the name in a book or in another program’s listing. The exceptions are PORTS.INC, because the MSX has no standard names for its I/O ports, and the prefixes in SUBROM.INC and EXTBIO.INC (sections 14.4 and 14.6).

Apart from the macro, every name is an EQU. An EQU gives a name a value and puts nothing in the program, so including a file adds names, not bytes. A source that includes all nine files and holds a single ret is still one byte long:

A:\>tanren /o:nocost.com nocost.tro 
Tatara MSX Linker v1.2.0 
Copyright (C) 2026 Javier Lavandeira 
https://tatara.tools 
 
1 modules, 5 records, ends at EOF. 
Wrote NOCOST.COM, 0100-0100 (1 bytes).
 

Each file starts with a comment that says how to use what is in it, and each name has a comment of one line that says what it is. What a BIOS routine or an MSX-DOS2 function needs in its registers, and what it gives back, is in the MSX books; the files do not repeat it, and neither does this manual.

14.2 Including them

Include a file by its name, as in chapter 4:

                include msxdos.inc
 

The names of an included file become names of your source. A label of your own cannot have the same name as one of them. beep: in a source that includes BIOS.INC, where BEEP is a BIOS entry, stops TATARA:

CLASH.AS(4): ERROR: this name already has a value.
 

Include only the files a source uses, and it will not meet names it does not need.

A file of names can be included more than once, in one source or in every module of a program, because each name gets the same value again (chapter 13).

The names are in upper case. TATARA does not tell upper and lower case apart unless the /C option is given (chapter 7), so ld a,(linl40) is the same as ld a,(LINL40). With /C, write the names as they are in the files:

CASEC.AS(4): ERROR: undefined symbol in an expression.
 

14.3 MSXDOS.INC and the system macro

MSXDOS.INC holds the numbers of the MSX-DOS functions, with the underscore that the MSX-DOS2 documentation gives them, such as _STROUT and _TERM0, and the name BDOS for 0005h, the address a program calls to reach them.

A program puts the function number in C, anything else the function needs in the other registers, and calls BDOS. The system macro does the first and the last of these in one line:

start:          ld      de,msg 
                system  _STROUT 
                system  _TERM0 
msg:            db      'Printed with system.',13,10,'$'
 

The listing shows what TATARA makes of each system line: the two instructions of the macro, each marked +.

  0000'   11 0D 00              start:          ld      de,msg 
                                                system  _STROUT 
  0003'   0E 09           +                     ld      c,_STROUT 
  0005'   CD 05 00        +                     call    BDOS 
                                                system  _TERM0 
  0008'   0E 00           +                     ld      c,_TERM0 
  000A'   CD 05 00        +                     call    BDOS
 

system changes C, and whatever the function itself changes. It always calls 0005h, which is right for a .COM program under MSX-DOS. A program that runs under Disk BASIC, or from a cartridge, reaches the functions at 0F37Dh instead, and has to make the call itself.

The functions below 31h exist in MSX-DOS1 as well. Those from 31h up need MSX-DOS2.

14.4 BIOS.INC and SUBROM.INC

BIOS.INC holds the entry points of the MAIN ROM, in address order.

Warning.  Under MSX-DOS, the MAIN ROM is not in memory at 0000h to 3FFFh: that page is RAM. A plain call to a BIOS entry from a .COM program therefore does not reach the BIOS. Five entries are the exception, because MSX-DOS provides them at the same addresses: RDSLT, WRSLT, CALSLT, ENASLT and CALLF. Every other entry needs an inter-slot call, through CALSLT.

CALSLT takes the slot of the routine in the high byte of IY, and its address in IX. The slot of the MAIN ROM is the first byte of EXPTBL, in the work area, so ld iy,(EXPTBL-1) loads it into the high byte of IY. This program sounds the buzzer, then prints a line with CHPUT, one character at a time:

                include msxdos.inc 
                include bios.inc 
                include workarea.inc 
                cseg 
start:          ld      iy,(EXPTBL-1)   ; the MAIN ROM slot, into IYh 
                ld      ix,BEEP 
                call    CALSLT 
                ld      hl,msg 
next:           ld      a,(hl) 
                or      a 
                jr      z,done 
                push    hl 
                ld      iy,(EXPTBL-1) 
                ld      ix,CHPUT 
                call    CALSLT 
                pop     hl 
                inc     hl 
                jr      next 
done:           ei 
                system  _TERM0 
msg:            db      'Printed by the BIOS.',13,10,0 
                end     start
 
A:\>bioscall 
Printed by the BIOS.
 

The ei at the end turns interrupts back on, since an inter-slot call leaves them off.

SUBROM.INC holds the entry points of the SUB ROM, which the MSX2 added. The SUB ROM uses some of the MAIN ROM’s names for different routines at different addresses: GRPPRT is 008Dh in the MAIN ROM and 0089h in the SUB ROM. So every name in SUBROM.INC starts with SUBROM_, as in SUBROM_GRPPRT, and the two files can be included together.

A SUB ROM routine is reached through the BIOS entry EXTROM, with its address in IX:

                ld      ix,SUBROM_REDCLK 
                call    EXTROM
 

That is the way from Disk BASIC or from a cartridge. From MSX-DOS it is more awkward: EXTROM is itself a BIOS entry, reached through CALSLT, and CALSLT uses IX for the address it calls, so it cannot hand a SUB ROM address to EXTROM in IX. The comment after EXTROM in BIOS.INC describes the way round it.

14.5 ERRORS.INC

ERRORS.INC holds the error codes of MSX-DOS and MSX-DOS2. Their names start with a dot, as in the MSX-DOS2 documentation: .NOFIL is 0D7h, “File not found”. A dot is allowed in a name (chapter 7). The codes count down from 0FFh, so this file, unlike the others, is in descending order.

An MSX-DOS2 function numbered 40h or higher returns an error code in A, and zero if it worked. A jr nz right after the call catches an error. A program can then hand the code to MSX-DOS2 with the function _TERM, which ends the program and prints the message for that code. This program tries to open a file that is not there:

                include msxdos.inc 
                cseg 
start:          ld      de,name 
                xor     a               ; open mode 0 
                system  _OPEN 
                jr      nz,failed       ; A is the error code 
                system  _TERM0 
failed:         ld      b,a 
                system  _TERM 
name:           db      'NOTHERE.TXT',0 
                end     start
 
A:\>openerr 
 
*** File not found
 

To test for one error in particular, compare A with its name: cp .NOFIL.

14.6 The other files

14.6.1 HOOKS.INC

A hook is five bytes in RAM that the system calls at a fixed moment: H.TIMI, for instance, is called at every timer interrupt, 50 or 60 times a second. An unused hook holds a ret. A program that takes over a hook saves its five bytes first, writes a jump to its own routine in their place, and puts the five bytes back before it ends. A hook left pointing into a program that has ended crashes the MSX at the next call.

Two hooks have two names each, because MSX-MIDI renamed them: H.ONKO and H.MDIN are both 0FF75h, and H.FRQI and H.MDTM are both 0FF93h. They are the same five bytes, not four hooks.

14.6.2 WORKAREA.INC

The work area is the part of RAM, from 0F323h up, where the system keeps its variables. In WORKAREA.INC the number at the start of each comment is the size of the variable in bytes. Read a one-byte variable with ld a,(LINL40), and a two-byte one with ld hl,(...); reading one with the other’s size gives an answer that is nearly right, and wrong.

14.6.3 PORTS.INC

The names of the I/O ports are Tatara’s own, since the MSX has no standard ones. Every port name starts with IO_, as in IO_VDPCMD for port 099h, and is written with three hex digits, the leading zero included.

14.6.4 EXTBIO.INC

The extended BIOS is how a program finds routines offered by a cartridge, such as MSX-DOS2’s own mapper routines or MSX-MIDI. The names start with EXTBIO_ and the name of the device, as in EXTBIO_DOS2_DEVICE, because the names the manuals give, such as INIT or EOF, would clash with names in almost any program. The comment at the start of the file explains how the extended BIOS is called.

14.6.5 ASCII.INC

The control codes, from CHR_NUL to CHR_DEL, and what the MSX does with each. Their values are decimal, unlike those of the other files, because character codes are usually written in decimal, as in db 13,10: CHR_CR is 13 and CHR_LF is 10.