#### The C64 OS Programmer's Guide is being written

This guide is being written and released and few chapters at a time. If a chapter seems to be empty, or if you click a chapter in the table of contents but it loads up Chapter 1, that's mostly likely because the chapter you've clicked doesn't exist yet.

Discussion of development topics are on-going about what to put in this guide. The discusssions are happening in the C64 OS Community Support Discord server, available to licensed C64 OS users.

# C64 OS PROGRAMMER'S GUIDE

## Chapter 4: Using the KERNAL → Math (module)

#### 16-bit Integer Arithmetic

These two routines are used to perform 16-bit multiplication and division. They can easily be used for 8-bit multiplication and division as well, since the multiplication of two 8-bit numbers so easily overflows an 8-bit result. 16-bit addition and subtraction are best handled using the standard macros defined in //os/s/:math.s, and floating point math operations are best handled using the BASIC ROM and its routines which are defined in //os/s/:float.s and //os/h/:float.h.

The workspace memory addresses used as the input and output parameters for these routines are in zero page, are the same workspace area used by the BASIC ROM for math operations, and are defined in //os/s/:math.s.

#### mul16

 Purpose Multiply two 16-bit integers. 0 None 2 bytes \$61, \$62, \$63, \$64, \$65, \$66, \$67, \$68 A, Y multplr → 16-bit multiplier multcnd → 16-bit multiplicand product ← 16-bit product

Description: This routine is used to multiply two 16-bit integers and may result in up to a 32-bit product. Multplr is modified by this routine. Multcnd is not affected by this routine. The input and output parameters are in zero page, and are defined by //os/s/:math.s.

#### div16

 Purpose Divide two 16-bit integers. 3 Status 2 bytes \$61, \$62, \$63, \$64, \$65, \$66, \$67 A, X, Y C → SET to round the result C → CLR to not round result divisor → 16-bit divisor dividnd → 16-bit dividend divrslt ← 16-bit quotient remandr ← remainder

Description: This routine is used to divide two 16-bit integers which results in a 16-bit quotient returned in divrslt. The 16-bit remainder is returned in remandr. If the carry is set when this routine is called, then a remainder that is greater than half the divisor is used to round the result up by one. Opting to use rounding causes the remainder to be multiplied by 2. Dividnd is modified by this routine. Divisor is not affected by this routine. The input and output parameters are in zero page, and are defined by //os/s/:math.s.

#### Integer ⇆ String Conversion

These three routines are used to convert an integer to a string or a string to an integer, in different bases up to a maximum of base 10. And lastly one routine to convert an 8-bit unsigned integer to hexadecimal, a string in base 16.

#### tostr

 Purpose Convert a 16-bit integer to string. 6 None 4 bytes \$61, \$62, \$63, \$64, \$65, \$66, \$67 A, X, Y divisor → base (maximum 10) dividnd → 16-bit integer value RegPtr ← pointer to string

Description: This routine is used to convert a 16-bit integer to a string representation. The string representation can be in any base from 2 to 10. Write the base in to divisor. The maximum base supported by this routine is 10. Divisor is a 16-bit number, so remember to write the \$00 into the divisor high byte. Write the 16-bit integer to be converted into dividnd. Call the routine, and a pointer to the string representation is returned as a RegPtr. The input parameters are in zero page, and are defined by //os/s/:math.s. This routine calls div16 internally. Divisor is not affected by this routine.

#### toint

 Purpose Convert a string representation of a number to a 16-bit integer. 9 A, X, Y 5 bytes \$61, \$62, \$63, \$64, \$65, \$66, \$67, \$68 A, X, Y multcnd → base (maximum 10) RegPtr → pointer to string A → string length (optional) multplr ← 16-bit integer value

Description: This routine is used to convert a string representation of a number to a 16-bit integer. The string representation can be in any base from 2 to 10. Write the base in to multcnd. The maximum base supported by this routine is 10. Multcnd is a 16-bit number, so remember to write the \$00 into the multcnd high byte. Read a pointer to a string into a RegPtr. If the number in the string ends with the end of the string, load #\$ff into the accumulator. Alternatively, load into the accumulator the string length to be converted. Call the routine, and the 16-bit integer value is returned in multplr. The input parameters are in zero page, and are defined by //os/s/:math.s. This routine calls mul16 internally. Multcnd is not affected by this routine.

#### tohex

 Purpose Convert a byte to string representation in hexadecimal. 12 A, X, Y 4 bytes None A, X, Y A → 8-bit unsigned integer (0 to 255) X ← Lower nybble as PETSCII character Y ← Upper nybble as PETSCII character

Description: This routine is used to convert a single byte into its string equivalent in hexadecimal. The technique used is much more efficient than that used by tostr. To convert a 16-bit number, this routine has to be called twice. Load the byte value into the accumulator, call this routine, and the X and Y registers are returned with PETSCII values from "0" to "9" and "A" to "F".