# QtARMSim User Manual

Table of contents

1. ARMSim own firmware API

1. Arithmetic subroutines
2. Display subroutines
3. Auxiliary subroutines

2. Qfplib (floating point library) API

1. Basic floating point operations
2. Conversion subroutines
3. Mathematical subroutines
4. String conversion subroutines

## 1. ARMSim own firmware API

This section describes the Application Programming Interface (API) of the ARMSim own firmware, which provides arithmetic, display, and auxiliary subroutines.

Please note that all the subroutines of this API follow the ARM convention for parameter passing and return. Thus, i) passed values use the registers from r0 to r3, and then the stack if required; ii) values are returned using r0, and r1 if required; and iii) all the subroutines modify only registers r0 to r3, while all the other are preserved.

### 1.1 Arithmetic subroutines

#### `divide(unsigned int dividend, unsigned int divisor)`

Performs the 32 bits unsigned division dividend/divisor, where r0 holds the dividend and r1 the divisor. The quotient is returned in r0 and the remainder in r1.

If r1 is 0 both quotient and remainder will be 0xFFFFFFFF which is an impossible result for a correct 32 bit division.

#### `sdivide(int dividend, int divisor)`

Performs the 32 bits signed division dividend/divisor, where r0 holds the dividend and r1 the divisor. The quotient is returned in r0 and the remainder in r1. The remainder always has the sign of the dividend ─unless the division is exact─.

If r1 is 0 both quotient and remainder will be 0x7FFFFFFF which is an impossible result for a correct 32 bit division.

If the dividend is 0x80000000 and the divisor is -1 the quotient returned is 0x80000000 as the positive range is exceeded. All the other combinations work as expected.

#### `sqrt(unsigned int val)`

Returns in r0 the positive, integer square root of the value passed in r0.

### 1.2 Display subroutines

#### `cls()`

Clears the display by filling it with the space character. Does not require nor return any value.

#### `fill(char c)`

Fills the display with the character passed in the LSB of r0. Does not return any value.

#### `printString(int column, int row, char *str)`

Shows the ASCIZ string whose address is passed in r2 starting at the display coordinates (column, row) where column is in r0 and row in r1.

The number of characters printed, i.e., the length of the string, is returned in r0.

Does not verify if the coordinates are inside or outside the display; nor if the string is printed in two rows or finishes out of the display area.

#### `printInt(int column, int row, int val)`

Shows the signed decimal value passed in r2 starting at the display coordinates (column, row) where column is in r0 and row in r1.

Only significant characters, plus a minus sign if required, are printed. The number of characters printed is returned in r0.

Does not verify if the coordinates are inside or outside the display; nor if the number is printed in two rows or finishes out of the display area.

#### `printUInt(int column, int row, unsigned int val)`

Shows the unsigned decimal value passed in r2 starting at the display coordinates (column, row) where column is in r0 and row in r1.

Only significant characters are printed. The number of characters printed is returned in r0.

Does not verify if the coordinates are inside or outside the display; nor if the number is printed in two rows or finishes out of the display area.

#### `printWord(int column, int row, unsigned int val)`

Shows the hexadecimal value of the word passed in r2 starting at the display coordinates (column, row) where column is in r0 and row in r1.

All 8 characters are printed, no value is returned.

Does not verify if the coordinates are inside or outside the display; nor if the number is printed in two rows or finishes out of the display area.

#### `printHalf(int column, int row, unsigned int val)`

Shows the hexadecimal value of the half word passed in r2 starting at the display coordinates (column, row) where column is in r0 and row in r1.

All 4 characters are printed, no value is returned.

Does not verify if the coordinates are inside or outside the display; nor if the number is printed in two rows or finishes out of the display area.

#### `printByte(int column, int row, unsigned int val)`

Shows the hexadecimal value of the byte passed in r2 starting at the display coordinates (column, row) where column is in r0 and row in r1.

All 2 characters are printed, no value is returned.

Does not verify if the coordinates are inside or outside the display; nor if the number is printed in two rows or finishes out of the display area.

#### `printFloat(int column, int row, float val, int format)`

Shows the decimal representation of the 32 bits floating point value passed in r2 starting at the display coordinates (col, row) where col is in r0 and row in r1, with the format specified in r3.

The format adheres to that used in the `qfp_float2str` function (0 specifies a basic format). The number of characters printed is returned in r0.

Does not verify if the coordinates are inside or outside the display; does not also verify if the number is printed in two files or finishes out of the display area.

#### `printf(int col, int fil, char *cad, ...)`

Shows the ASCIZ formatted string whose address is passed in r2 starting at the display coordinates (col, row) where col is in r0 and row in r1. It is a simple version of the standard C `printf` function.

The string includes a series of format specifiers preceded by the '%' character. Each specifier corresponds to one of the parameters passed after the string, in sequential order.

The format specifiers are:

- %i or %d: a signed integer.
- %u: an unsigned integer.
- %x or %w: a 32 bits integer (word) in hexadecimal.
- %h: a 16 bits integer (half) in hexadecimal.
- %b: a byte in hexadecimal.
- %c: a character.
- %f: a 32 bits floating point value (basic format).
- %s: an ASCIZ text string.

All parameters are 32 bits values.

In addition to the previous format specifiers, the function accepts the '\n' (CR) character to continue printing at the beginning of the next line, and '\t' (TAB) to force the next character to be placed at the next column multiple of 5. The '%' character can be printed by writing '%%'. If an unknown specifier is found after '%', a question mark '?' is printed instead of '%'.

The number of display positions used is returned in r0. That is, the number of characters printed plus the spaces generated by each '\t' and the spaces to the end of a line after a '\n'.

### 1.3 Auxiliary subroutines

#### `cor2dir(int col, int row)`

Returns in r0 the address in display memory corresponding to the given coordinates. It does not check if the coordinates are within the correct range. The column number is passed in r0 and the row in r1, both starting at 0.

#### `dir2cor(char *dir)`

Returns the coordinates corresponding tho the given display memory address, passed in r0. It does not check if the address is within the correct range. Returns the column in r0 and the row in r1, both starting at 0.

## 2. Qfplib (floating point library) API

The QtARMSim firmware includes Qfplib: an ARM Cortex-M0 floating-point library in 1 kbyte `<https://www.quinapalus.com/qfplib.html>`, (c) Mark Owen. Thanks to this library, IEEE 754 single precision floating point operations can be performed on the ARMSim simulator.

Please note that all the subroutines of this API follow the ARM convention for parameter passing and return. Thus, i) passed values use the registers from r0 to r3, and then the stack if required; ii) values are returned using r0, and r1 if required; and iii) all the subroutines modify only registers r0 to r3, while all the other are preserved.

The next sections describe: the basic floating point operations, the conversion subroutines, the mathematical subroutines, and the string conversion subroutines.

### 2.1 Basic floating point operations

#### `qfp_fadd(float f1, float f2)`

Performs the floating point addition. r0 and r1 hold the operands, and the result is returned in r0.

#### `qfp_fsub(float m, float s)`

Performs the floating point subtraction. r0 holds the minuend and r1 holds the subtrahend, and the result is returned in r0.

#### `qfp_fmul(float f1, float f2)`

Performs the floating point multiplication. r0 and r1 hold the operands, and the result is returned in r0.

#### `qfp_fdiv(float dd, float ds)`

Performs the floating point division. r0 holds the dividend and r1 holds the divisor, and the quotient is returned in r0.

#### `qfp_fcmp(float f1, float f2)`

Performs the comparison between the floating point numbers in r0 –f1– and r1 –f2–. Returns in r0 an integer whose value is 0 if both are equal, -1 if r0 < r1 and +1 if r0 > r1

### 2.2 Conversion subroutines

#### `qfp_float2int(float f)`

Converts the float in r0 to signed integer, rounding towards -Inf. The integer is returned in r0.

#### `qfp_float2fix(float f, int d)`

Converts the float in r0 to signed fixed point, with the number of fractionary bits in r1. The fixed point value is returned in r0.

#### `qfp_float2uint(float f)`

Converts the float in r0 to unsigned integer, rounding towards 0 if positive. Any negative float returns 0. The unsigned integer is returned in r0.

#### `qfp_float2ufix(float f, int d)`

Converts the float in r0 to unsigned fixed point, with the number of fractionary bits in r1. Any negative float returns 0. The fixed point value is returned in r0.

#### `qfp_int2float(int i)`

Converts the signed integer in r0 to float. The floating point value is returned in r0.

#### `qfp_fix2float(int fx, int n)`

Converts the fixed point value in r0, with the number of fractionary bits in r1, to floating point. The floating point value is returned in r0.

#### `qfp_uint2float(unsigned int u)`

Converts the unsigned integer in r0 to float. The floating point value is returned in r0.

#### `qfp_ufix2float(unsigned int fx, int n)`

Converts the unsigned fixed point value in r0, with the number of fractionary bits in r1, to floating point. The floating point value is returned in r0.

### 2.3 Mathematical subroutines

#### `qfp_fcos(float x)`

Returns in r0 the cosine of the angle held in r0, expressed in radians.

#### `qfp_fsin(float x)`

Returns in r0 the sine of the angle held in r0, expressed in radians.

#### `qfp_ftan(float x)`

Returns in r0 the tangent of the angle held in r0, expressed in radians.

#### `qfp_fatan2(float y, float x)`

Returns in r0 the angle in radians whose tangent is given by r0/r1. r0 –y– can be viewed as the sine of the angle or the y coordinate of the end of a segment starting at the origin and whose angle with the x axis is returned by the subroutine. Accordingly, r1 –x– can be viewed as the cosine or the x coordinate.

#### `qfp_fexp(float x)`

Returns in r0 the value of e raised to r0.

#### `qfp_fln(float x)`

Returns in r0 the natural logarithm of r0.

#### `qfp_fsqrt(float x)`

Returns in r0 the square root of r0.

### 2.4 String conversion subroutines

#### `qfp_float2str(float f, char *str, unsigned int format)`

Stores in the address given in r1 the string representing the floating point value present in r0. No value is returned. When r2 is 0, a default format is used, otherwise the format is specified as follows (bxx is bit xx of r2):

- b7..b0: number of significant figures.
- b15..b8: -(minimum exponent printable in F format).
- b23..b16: (maximum exponent printable in F format)-1.
- b24: output positive mantissas with ' '.
- b25: output positive mantissas with '+'.
- b26: output positive exponents with ' '.
- b27: output positive exponents with '+'.
- b28: suppress trailing zeros in fraction.
- b29: fixed-point output: b7..0 give number of decimal places.

The default format is 0x18060406.

Note that if b28 is set (as it is in the default format value) the code will write the trailing decimal point and zeros to the output buffer before truncating the string. Thus, it is essential that the output buffer is large enough to accommodate these characters temporarily.

Overall accuracy is sufficient to print all exactly-representable integers up to 10^8 correctly in 0x18160408 format

#### `qfp_str2float(float *f, char *str, char **endptr)`

Converts the string starting at the address contained in r1 to a float and stores it to the address contained in r0. At the address contained in r2 is placed the address of the first non convertible character, unless r2 contains 0. The return value in r0 is 0 in case of success or 1 in case of failure, that is, the string is not convertible.