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