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.
Module offset 0
Communication registers None
Stack requirements 2 bytes
Zero page usage $61, $62, $63, $64, $65, $66, $67, $68
Registers affected A, Y
Input parameters multplr → 16-bit multiplier
multcnd → 16-bit multiplicand
Output parameters 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.
Module offset 3
Communication registers Status
Stack requirements 2 bytes
Zero page usage $61, $62, $63, $64, $65, $66, $67
Registers affected A, X, Y
Input parameters C → SET to round the result
C → CLR to not round result
divisor → 16-bit divisor
dividnd → 16-bit dividend
Output parameters 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.
Module offset 6
Communication registers None
Stack requirements 4 bytes
Zero page usage $61, $62, $63, $64, $65, $66, $67
Registers affected A, X, Y
Input parameters divisor → base (maximum 10)
dividnd → 16-bit integer value
Output parameters 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.
Module offset 9
Communication registers A, X, Y
Stack requirements 5 bytes
Zero page usage $61, $62, $63, $64, $65, $66, $67, $68
Registers affected A, X, Y
Input parameters multcnd → base (maximum 10)
RegPtr → pointer to string
A → string length (optional)
Output parameters 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.
Module offset 12
Communication registers A, X, Y
Stack requirements 4 bytes
Zero page usage None
Registers affected A, X, Y
Input parameters A → 8-bit unsigned integer (0 to 255)
Output parameters 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".



KERNAL Modules in Alphabetical Order

KERNAL Modules in Module Lookup Table Order

Return to Using the KERNAL → KERNAL Modules


Table of Contents



This document is subject to revision updates.

Last modified: Apr 20, 2023