Signed or unsigned ? (by Ihor Nehrutsa)
LDmicro v2.3 pic16.cpp code fragment:
...
//------------------------------------------------------------
// Write a subroutine to do a 16x16 signed multiply. One operand in
// Scratch1:Scratch0, other in Scratch3:Scratch2, result in Scratch3:Scratch2.
//------------------------------------------------------------
static void WriteMultiplyRoutine(void)
{
DWORD result3 = Scratch5;
DWORD result2 = Scratch4;
DWORD result1 = Scratch3;
DWORD result0 = Scratch2;
DWORD multiplicand0 = Scratch0;
DWORD multiplicand1 = Scratch1;
DWORD counter = Scratch6;
DWORD dontAdd = AllocFwdAddr();
DWORD top;
FwdAddrIsNow(MultiplyRoutineAddress);
Instruction(OP_CLRF, result3, 0);
Instruction(OP_CLRF, result2, 0);
Instruction(OP_BCF, REG_STATUS, STATUS_C);
Instruction(OP_RRF, result1, DEST_F);
Instruction(OP_RRF, result0, DEST_F);
Instruction(OP_MOVLW, 16, 0);
Instruction(OP_MOVWF, counter, 0);
top = PicProgWriteP;
Instruction(OP_BTFSS, REG_STATUS, STATUS_C);
Instruction(OP_GOTO, dontAdd, 0);
Instruction(OP_MOVF, multiplicand0, DEST_W);
Instruction(OP_ADDWF, result2, DEST_F);
Instruction(OP_BTFSC, REG_STATUS, STATUS_C);
Instruction(OP_INCF, result3, DEST_F);
Instruction(OP_MOVF, multiplicand1, DEST_W);
Instruction(OP_ADDWF, result3, DEST_F);
FwdAddrIsNow(dontAdd);
Instruction(OP_BCF, REG_STATUS, STATUS_C);
Instruction(OP_RRF, result3, DEST_F);
Instruction(OP_RRF, result2, DEST_F);
Instruction(OP_RRF, result1, DEST_F);
Instruction(OP_RRF, result0, DEST_F);
Instruction(OP_DECFSZ, counter, DEST_F);
Instruction(OP_GOTO, top, 0);
Instruction(OP_RETURN, 0, 0);
}
//------------------------------------------------------------
...
I think that this routine is an UNSIGNED multiplication.
But we need a signed multiplication.
Application Notes for reference:
PIC: AN526,AN544,AN617
AVR: AVR200, AVR201, AVR202
WriteMultiplyRoutine(..) is equivalent to mpy16u, not mpy16s
from avr200.asm.
Am I right or wrong?
Has anyone had problems with multiplication with negative numbers in your projects?