BASIC Routines In Main-ROM
This page was last modified 23:06, 29 December 2021 by Redman. Based on work by Pgimeno and Gdx and others.

Below are some routines used by the BASIC whose locations are guaranteed by ASCII. There are other routines as well that have practically stayed on same address through all generations of MSX, but as they are not officially documented or used, they have not made it to this list.

Contents

Math-pack routines

Math-pack routines are mathematical routine set but also moving, comparison and conversion of numbers that are coded on 2 bytes for integer, 3 for string descriptor, 4 for single precision or 8 for double precision as below. Single and double precision digits are stored in BCD format (norm IEEE 754-1985).

Integer value:
3rd byte: Less significant 8 bits of the value
4th byte: The sign (bit 7) and most significant 7 bits of the value

Single/Double precision value:
1st byte: The sign (bit 7) and exponent
2nd byte: The digit before and after the decimal point
3rd byte: 2nd and 3rd digit after the decimal point
4th byte: 4th and 5th digit after the decimal point <- Until here for single precision
5th byte: 6th and 7th digit after the decimal point
6th byte: 8th and 9th digit after the decimal point
7th byte: 10th and 11th digit after the decimal point
8th byte: 12th and 13th digit after the decimal point

String descriptor:
3rd byte: Less significant 8 bits of the string address
4th byte: Most significant 8 bits of the string address

The values type must be specified to 0F663h (VALTYP). Value type practically describes how many bytes are used from memory.

VALTYP Description
2 Integer
3 String
4 Single precision number
8 Double precision number


The decimal accumulator (DAC) is the value stored to 0F7F6h (16 bytes).
The argument (ARG) is the value stored to 0F847h (16 bytes).

Basic Operations

268CH (DECSUB)
Function:	DAC <-- DAC - ARG
Modify:		All registers
Note:		DAC and ARG must be double precision.
269AH (DECADD)
Function:	DAC <-- DAC + ARG
Modify:		All registers
Note:		DAC and ARG must be double precision.
26FAH (DECNRM)
Function:	Normalises DAC
Modify:		All registers
Notes:		- DAC must be double precision.
		- Remove the useless zeros from mantissa part. (eg 0.00123 -> 0.123E-2)
273CH (DECROU)
Function:	Rounds DAC
Modify:		All registers
Note:		DAC must be double precision.
27E6H (DECMUL)
Function:	DAC <-- DAC * ARG
Modify:		All registers
Note:		DAC and ARG must be double precision.
289FH (DECDIV)
Function:	DAC <-- DAC / ARG
Modify:		All registers
Note:		DAC and ARG must be double precision.
314Ah (UMULT)
Function:	DE <-- BC * DE
Modify:		A, BC, DE
Note:		The result is also placed in DAC+2 (2-byte)
3167h (ISUB)
Function:	HL <-- DE - HL 
Modify:		All registers
Note:		The result is also placed in DAC+2 (2-byte)
3172h (IADD)
Function:	HL <-- DE + HL
Modify:		All registers
Note:		The result is also placed in DAC+2 (2-byte)
3193h (IMULT)
Function:	HL <-- DE * HL
Modify:		All registers
Note:		The result is also placed in DAC+2 (2-byte)
31E6h (IDIV)
Function:	HL <-- DE / HL
Modify:		All registers
Note:		The result is also placed in DAC+2 (2-byte)
323Ah (IMOD)
Function:	HL <-- DE mod HL (DE <-- DE/HL)
Modify:		All registers
Note:		The result is also placed in DAC+2 (2-byte)

Power

37C8h (SGNEXP)
Function:	DAC <-- DAC ^ ARG (single precision)
Modify:		All registers
37D7h (DBLEXP)
Function:	DAC <-- DAC ^ ARG (double precision)
Modify:		All registers
383Fh (INTEXP)
Function:	DAC <-- DE ^ HL (integer) 
Modify:		All registers

Trigonometric Functions

2993h (COS)
Function:	DAC <-- COS(DAC) (specified type)
Modify:		A, BC, DE, HL
29ACh (SIN)
Function:	DAC <-- SIN(DAC) (specified type)
Modif:		A, BC, DE, HL
29FBh (TAN)
Function:	DAC <-- TAN(DAC) (specified type)
Modify:		A, BC, DE, HL
2A14h (ATN)
Function:	DAC <-- ATN(DAC) (specified type)
Modify:		A, BC, DE, HL

Other Functions

2A72h (LOG)
Function:	DAC <-- LOG(DAC) (specified type)
Modify:		A, BC, DE, HL
2AFFh (SQR)
Function:	DAC <-- SQR(DAC) (specified type)
Modify:		A, BC, DE, HL
2B4Ah (EXP)
Function:	DAC <-- EXP(DAC) (specified type)
Modify:		A, BC, DE, HL
2BDFh (RND)
Function:	DAC <-- RND(DAC) (specified type)
Modify:		A, BC, DE, HL
2E71H (SIGN)
Function:	A <-- Sign of DAC
Modify:		A
2E82H (ABSFN)
Function:	DAC <-- ABS(DAC)
Modify:		A, BC, DE, HL
2E8DH (NEG)
Function:	DAC <-- NEG(DAC)
Modify:		A, H, L
2E97H (SNG)
Function:	DAC <-- SNG(DAC)
Modify:		A, H, L
Note:		Result is an integer (2 bytes).

Moving Values

2C4Dh (MAF)
Function:	ARG <-- DAC (double precision)
Modify:		A, B, DE, HL
2C50h (MAM)
Function:	ARG <-- (HL) (double precision)
Modify:		A, B, DE, HL
2C53h (MOV8DH)
Function:	(DE) <-- (HL) (double precision)
Modify:		A, B, DE, HL
2C59h (MFA)
Function:	DAC <-- ARG (double precision)
Modify:		A, B, DE, HL
2C5Ch (MFM)
Function:	DAC <-- (HL) (double precision)
Modify:		A, B, DE, HL
2C67h (MMF)
Function:	(HL) <-- DAC (double precision)
Modify:		A, B, DE, HL
2C6Ah (MOV8HD)
Function:	(HL) <-- (DE) (double precision)
Modify:		A, B, DE, HL
2C6Fh (XTF)
Function:	(SP) <--> DAC (double precision)
Modify:		A, B, DE, HL
2CC7h (PHA)
Function:	ARG --> (SP) (double precision)
Modify:		A, B, DE, HL
2CCCh (PHF)
Function:	DAC --> (SP) (double precision)
Modify:		A, B, DE, HL
2CDCh (PPA)
Function:	(SP) --> ARG (double precision)
Modify:		A, B, DE, HL
2CE1h (PPF)
Function:	(SP) --> DAC (double precision)
Modify:		A, B, DE, HL
2EB1h (PUSHF)
Function:	DAC --> (SP) (single precision)
Modify:		DE
2EBEh (MOVFM)
Function:	DAC <-- (HL) (single precision)
Modify:		BC, DE, HL
2EC1h (MOVFR)
Function:	DAC <-- CBED (single precision, C contains the 1st byte)
Modify:		DE
2ECCh (MOVRF)
Function:	CBED <-- DAC (single precision, C contains the 1st byte)
Modify:		BC, DE, HL
2ED6h (MOVRMI)
Function:	CBED <-- (HL) (single precision, C contains the 1st byte)
Modify:		BC, DE, HL
2EDFh (MOVRM)
Function:	BCDE <-- (HL) (single precision, B contains the 1st byte)
Modify:		BC, DE, HL
2EE8h (MOVMF)
Function:	(HL) <-- DAC (single precision)
Modify:		A, B, DE, HL
2EEBh (MOVE)
Function:	(HL) <-- (DE) (single precision)
Modify:		BC, DE, HL
2EEFh (VMOVAM)
Function:	ARG <-- (HL) (specified type)
Modify:		BC, DE, HL
2EF2h (MOVVFM)
Function:	(DE) <-- (HL) (specified type)
Modify:		BC, DE, HL
2EF3h (VMOVE)
Function:	(HL) <-- (DE) (specified type)
Modify:		BC, DE, HL
2F05h (VMOVFA)
Function:	DAC <-- ARG (specified type)
Modify:		BC, DE, HL
2F08h (VMOVFM)
Function:	DAC <-- (HL) (specified type)
Modify:		BC, DE, HL
2F0Dh (VMOVAF)
Function:	ARG <-- DAC (specified type)
Modify:		BC, DE, HL
2F10h (VMOVMF)
Function:	(HL) <-- DAC (specified type)
Modify:		BC, DE, HL

Comparison Values

2F21h (FCOMP)
Function:	Compare CBED with DAC (single precision, C contains the 1st byte)
Output:		A = 0 if CBED = DAC, 1 if CBED < DAC, -1 if CBED > DAC
Modify:		HL
2F4Dh (ICOMP)
Function:	Compare DE with HL (integer)
Output:		A = 0 if DE = HL, 1 if DE < HL, -1 if DE > HL
Modify:		HL
2F5Ch (XDCOMP)
Function:	Compare ARG with DAC (double precision)
Output:		A = 0 if ARG = DAC, 1 if ARG < DAC, -1 if ARG > DAC
Modify:		All registers

Conversion Values

30CFh (INT)
Function:	DAC <-- INT(DAC) (specified type)
Input:		VALTYP (0F663h) = 4 or 8
Output:		VALTYP (0F663h) = 2
Modify:		All registers
3299h (FIN)
Function:	Convert a numerical floating-point number in a string to a real number in DAC.
Input:		HL= Pointer to the string
Output:		DAC= Result
		C = 0 if floating-point, FFh if is not the cas
		B = Number of digits after the floating-point
		D = Total number of digits
3225h (FOUT)
Function:	Convert a numerical number stored in DAC to a string. (unspecified format)
Output:		HL= Pointer to resulting string
3426h (PUFOUT)
Function:	Convert a numerical number stored in DAC to a string. (specified format)
Input:		A = Desired format
			Bit7 = O for no specified format, 1 to specify the format
			Bit6 = 1 to separate each 3 digits with a comma 
			Bit5 = 1 to replace the space in the head by *
			Bit4 = 1 to put $ in the head
			Bit3 = 1 to put + if positive value
			Bit2 = 1 to place the sign the sign behind
			Bit1 = Unused
			Bit0 = 0 for Fixed point, 1 floating-point
		B = Number of digit before the floating-point
		C = Number of digit after the floating-point
Output:		HL= Pointer to resulting string
371Ah (OUTB)
Function:	Converts 2-byte integer in DAC+2, 3 to a binary expression string. 
Input:		VALTYP (0F663h) must be 2
Output:		HL= Pointer to resulting string
Modify:		All registers
371Eh (OUTO)
Function:	Converts 2-byte integer in DAC+2, 3 to an octal expression string. 
Input:		VALTYP (0F663h) must be 2
Output:		HL= Pointer to resulting string
Modify:		All registers
3722h (OUTH)
Function:	Converts 2-byte integer in DAC+2, 3 to a hexadecimal expression string. 
Input:		VALTYP (0F663h) must be 2
Output:		HL= Pointer to resulting string
Modify:		All registers
2F8Ah (FRCINT)
Function:	Converts DAC to a 2-byte integer (DAC+2, +3)
Output:		VALTYP (0F663h) = 2
Modify:		All registers
2FB2h (FRCSNG)
Function:	Converts DAC to a single precision number
Output:		VALTYP (0F663h) = 4
Modify:		All registers
303Ah (FRCDBL)
Function:	Converts DAC to a double precision number 
Output:		VALTYP (0F663h) = 8
Modify:		All registers
30BEh (FIXER)
Function:	DAC <-- SGN(DAC) * INT(ABS(DAC))
Output:		VALTYP (0F663h) = 2, 4 or 8
Modify:		All registers

Method for calling a Math-pack routine under MSX-DOS

Under MSX-DOS, all pages contain the Main-RAM. The Math-pack routines are spread over two banks of the Main-Rom. So, to call a routine you must select the Main-ROM on page 4000h~7FFFh before calling a Math-Pack routine. And after the call as the Main-ROM remains on the page 4000h~7FFFh, you have to re-select the Main RAM on this page to back to return to the initial state of the memory in slots.

Assembly example:

CALSLT	equ 001Ch		; Inter-Slot call routine
EXPTBL	equ 0FCC1h		; Byte indicating the Main-ROM slot
CALBAS	equ 00159h		; Address of the Math-pack routine

CALBAS_FROM_DOS:
	ld iy,(EXPTBL-1)	; Location of the Main-ROM in IY
	ld ix,CALBAS		; Address of the Math-pack routine in IX
	jp CALSLT		; Call the Math-pack routine

Extra routines

	org 0406fh

	ld ix,0406fh
	jp CALBAS_FROM_DOS
;---
	org 04666h

	ld ix,04666h
	jp CALBAS_FROM_DOS
;---
	org 04eb8h

	ld ix,04eb8h
	jp CALBAS_FROM_DOS
;---
	org 05439h

	ld ix,05439h
	jp CALBAS_FROM_DOS
;---
	org 05597h

getypr:
	ld a,(valtyp)
	cp 8
	jr nc,double
	sub 3
	or a
	scf
	ret

double:
	sub 3
	or a
	ret
;---
	org 066a7h

ppswrt:
	pop af
	ret

Routines from the Basic interpreter

ASCII has also guaranteed some routines from the Basic interpreter to help the creation of new extended instructions of Basic (instructions preceded by CALL). The Basic has two instructions reserved (CMD and IPL) that have never been used. You can use them to make your own instructions.

409Bh	READYR	Start basic
42B2h	CRUNCH	Convert the Basic instruction by an intermediate code
4601H	NEWSTT	Execute a text
4666h	CHRGTR	Extract one character from text
4C64h	FRMEVL	Evaluate an expression in text
521Ch	GETBYT	Evaluate an expression in 1-byte integer type.
542Fh	FRMQNT	Evaluate an expression in 2-byte integer type.
5EA4h	PTRGET	Obtain the address for the storage of a variable
67D0h	FRESTR	Free temporary string descriptor

Routines used by Disk ROM internally

These addresses are used by disk ROM (that is expected to run on any MSX) but are not officially documented.

2F99H		Copy HL in DAC
3042H		Convert DAC from single to double
30D1H		Convert double to integer
325CH		Multiply single
3FD6H		Pointer to zero byte
406FH		BASIC error
4173H		Execute statement
4253H		Convert linenumbers to pointers
46FFH		convert unsigned integer to single
4756H		evaluate word operand and check for 0-32767 range
475AH		illegal function call
4AFFH		return interpreter output to screen
4C5FH		evaluate =expression
517AH		convert DAC to other type
520FH		evaluate experssion and convert to positive integer
521BH		evaluate next byte operand
521FH		convert to byte
537BH		convert DAC to text, unformatted
5432H		convert address to integer
54F7H		convert pointers to linenumbers
5597H		GETYPR
6627H		allocate temp string
668EH		allocate stringspace
6A0EH		evaluate filename
6A6DH		get I/O channel pointer
6AFAH		open I/O channel
6B24H		close I/O channel
6C1CH		close all I/O channels
6E41H		resume point character putback routine
6E92H		start of BSAVE statement
6EC6H		start of BLOAD statement
6EF4H		finish BLOAD
6F0BH		evaluate BLOAD/BSAVE adres operand
6F1DH		skip strong cassette devicecheck
7323H		newline to OUTDO if not at start of line
7328H		newline to OUTDO
739AH		quit loading & start (headloop/executing)
7D17H		continue start of MSX-BASIC without executing BASIC programs in ROM
7D2FH		initialize BASIC screen
7D31H		BASIC initscreen (without INITXT & CNSDFG)
7DE9H		start basic program in extension rom
7E14H		start MSX-BASIC program in ROM