operator (new in SX/B 1.5x, and */ has been added, as
well) returns the upper 16 bits from a 16-bit x 16-bit
multiplication. The * operator will return the lower 16 bits
of the product.
Note how the 32-bit value is returned to the caller as
two words, separated by a comma, low-word first. So how
do we collect this 32-bit value? Let’s start with variables to
And here’s how we can use the function in a program.
What’s the advantage? Well, the compiler will
automatically insert startup code that makes the pin an
output, so we don’t have to worry about anything beyond
the declaration. That way, we can write directly to the pin
knowing that the appropriate TRIS register has been set up
In a lot of my older programs, I would enable the SX
pull-ups on any unused pin to minimize current draw. It’s
even easier now. Let’s say that we have just the one LED as
above. By using the following declarations, we don’t have to
worry about TRIS or PLP register settings in our code, which
lets us focus solely on the application. Note how PIN works
with groups and individual I/O pins.
result = MULT32 $FFFF, $0100
resultHi = __PARAM3, __PARAM4
The first part is obvious, I’m sure; we call the function
and assign it to result. But this only gets us the lower 16 bits.
To get the upper 16 bits, we have to grab them ourselves.
The high word from the function will be returned in
__PARAM3 (LSB) and __PARAM4 (MSB). This also demonstrates how to move two bytes into a word with just one line
There is a method for collecting all four bytes from this
function without the second line of code above — but we
must use an array as the target variable. So, we could do
And now we just need one line of code:
bigVal = MULT32 $1234, $10
One of the interesting things about the SX-Key tool is
that it will let us view 32-bit values in the Debug window.
We can set up a WATCH declaration like this:
WATCH result, 32, UHEX
If we run the program in Debug mode with a BREAK
instruction after the function call, we’ll see the 32-bit result.
PIN DOWN YOUR I/O
One of the latest updates to SX/B is the PIN definition
that became available in version 1.51. In the past, we might
define an I/O pin like this:
Now we can do this:
RA INPUT PULLUP
RB INPUT PULLUP
RC INPUT PULLUP
RC.0 OUTPUT NOPULLUP
The final declaration overrides the definition for RC.0
from the group above; this way, we can define the unused
pins as a group instead of one at a time.
It’s important to understand that generation of PIN
start-up code is enabled even when the NOSTARTUP
option for the PROGRAM directive is specified. The
available options for PIN are INPUT, OUTPUT, PULLUP,
NOPULLUP, TTL, CMOS, and SCHMITT — and when
multiple options are used, they are space-delimited.
INTERRUPTS WITHOUT IRRITATION
Before I get too far into this section, let me start by
saying that interrupts are always tricky but that SX/B 1.5x
does make them a bit easier to cope with. With SX/B 1.5x,
we can simply specify how frequently (in interrupts per
second) that the ISR should run and the compiler will take
care of the rest, setting the OPTION register and
the RETURNINT value automatically. Let’s start with a very
INTERRUPT NOPRESERVE 1000
IF timer = Cycles THEN
timer = 0
The purpose of this code is to toggle the state of
an LED every N milliseconds, defined by the program
constant called Cycles. Note that the end of the
INTERRUPT declaration line specifies 1000 — this will cause
the program to set up the interrupt such that it runs once
every millisecond. If we specify an ISR rate that that won’t
work with the FREQ directive, the compiler will complain of
an invalid parameter.