Assembly Notes

I’m putting all my notes in one place. I talk about important instructions, or instructions that are tricky to use. I also have recipes for frequently used code blocks.

Mnemonics

This section describes each instruction in detail.

ADB / SBB - 16-Bit addition and subtraction

ADB 16-bit add [P+1,P] + (B,A) -> [P+1,P] P+1->P

If P is pointing to XL, then ADB will add the following. If A overflows, the carry is added to XH.

A + XL -> XL
B + XH -> XH

The following program will add &10FF+&0102=&1201

     BEFORE| AFTER
REG | VAL  | VAL
XH  | &10  | &12
XL  | &FF  | &01
B   | &01
A   | &02
P   | XL   | XH

lp      XH_REG  # XH -> P
lia     &10 
exam            # A  [P]
lp      XL_REG
lia     &FF
exam            # A  [P] => X now points to number

lp      XL_REG
lib     1
lia     2
adb             # [P+1,P] + (B,A) -> [P+1,P], P+1->P

And if you wanted to store the result, you can use:

# store the result
lp      XH_REG
ldm             # [P] -> A
lidp    resultHigh
std             # A -> [DP]
lp      XL_REG
ldm             # [P] -> A
lidp    resultLow
std

Recipies

Topics here are quick one off solutions for common tasks. Copy, paste and modify when needed.

Copy X to Y

There are times when you need to be able to do adjust the starting address of your Y register. Unfortunately, things like a 16-add using adb are only done on X. The solution is to do your work using X, then copy X to Y.

# copy X to Y
lp      XH_REG
ldm
lp      YH_REG
exam
lp      XL_REG
ldm
lp      YL_REG
exam

Copy A to B or B to A

Normally when you want to put the value of A in to B, you would use exab. But this destroys the contents of A. For the times you want to copy A to B, you can use this one-two combo.

# Copy B to A
lp      B_REG           # point P to B
ldm                     # [P] -> A, A=B

Close to the same idea, you can copy A to B.

# copy A to B
exab                    # A  B, B=A
lp      B_REG           # point P to B
ldm                     # [P] -> A, A=B, A & B now equal

8-Bit Multiply and Divide Routines

I was a little surprised to find the PC–1360’s SC61860 CPU instruction set didn‘t have any instructions for multiplication or division. I especially found it hard to believe because the 1360 and 1403 are scientific calculators. What the heck?

So I wrote up a couple assembly routines. They work for 8-bit numbers, but they don‘t handle overflow. So 128*3 will equal 128 instead of 384.

##############################################################################
## divide - Divide B by A
## 
## INPUT:        B reg dividend
##               A reg divisor
## OUTPUT:       A reg quotent
##               B reg remainder
##############################################################################
divide:         push                    # hold A
                lp      K_REG
                ra                      # clear A
                exam                    # 0 -> K, K will be our quotient
                pop                     # restore A

add1:           inck                    # increment the quotient
                lp      B_REG           # Point P to B reg
                sbm                     # [P] - A -> [P], B=B-A
                #if B=0 we are done
                cpim    0               # B == 0?
                jpz     done1           # yup, B == 0
                #if B < A we are done, and B will be the REMAINDER
                cpma                    # compare B and A
                jpc     done1           # B < A
                jp      add1

done1:          lp      K_REG           # K contains the quotent
                exam                    # A  [P], A now contains K, the QUOTENT
                rtn


##############################################################################
# Multiply - multiply B by A
# 
# INPUT:        B reg multiplicant
#               A reg multiplyer
# OUTPUT:       A reg is the product
# 
##############################################################################
multiply:       cpia    0
                jpz     done0           # multiplying by 0
                lp      B_REG
                cpim    0
                jpz     done0           # multiplying by 0

                deca                    # correct for loop count
                jpc     done0           # multiplied by 0
                push                    # A to the stack for LOOP call

                exab                    # copy B to A ...
                push                    #   A to the stack to hold B value
                exab                    #   B contains original value
                pop                     # ... A now equals B

                lp      B_REG           # point P to B reg
add2:           adm                     # [P] + A -> [P], B=B+A
                loop    add2            
                sbm                     # [P] - A -> P,B=B-A to correct for one extra addition in loop

done2:          exab                    # A  B, A now contains product
                rtn

done0:          ra                      # product will be 0
                rtn