mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-22 18:06:40 +01:00
1503 lines
30 KiB
C
1503 lines
30 KiB
C
#include "asmUtil.h"
|
|
#include "cpu.h"
|
|
|
|
|
|
#pragma callee_saves mathPrvU8bitswap
|
|
uint16_t mathPrvU16from2xU8(uint8_t hi, uint8_t lo) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" mov DPH, DPL \n"
|
|
" pop B \n"
|
|
" pop A \n"
|
|
" pop DPL \n"
|
|
" push DPL \n"
|
|
" push A \n"
|
|
" push B \n"
|
|
" ret \n"
|
|
);
|
|
(void)hi;
|
|
(void)lo;
|
|
}
|
|
|
|
//a is hi
|
|
uint32_t mathPrvU32from4xU8(uint8_t hi, uint8_t midhi, uint8_t midlo, uint8_t lo) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" push _R0 \n"
|
|
" mov A, #-5 \n" //point to first pushed arg (last param - lo)
|
|
" add A, sp \n"
|
|
" mov R0, A \n"
|
|
" mov A, DPL \n"
|
|
" mov DPL, @R0 \n"
|
|
" inc R0 \n"
|
|
" mov DPH, @R0 \n"
|
|
" inc R0 \n"
|
|
" mov B, @R0 \n"
|
|
" pop _R0 \n"
|
|
" ret \n"
|
|
);
|
|
(void)hi;
|
|
(void)midhi;
|
|
(void)midlo;
|
|
(void)lo;
|
|
}
|
|
|
|
|
|
#pragma callee_saves mathPrvU8bitswap
|
|
uint8_t mathPrvU8bitswap(uint8_t val) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" mov B, #8 \n"
|
|
"00003$: \n"
|
|
" xch A, DPL \n"
|
|
" rrc A \n"
|
|
" xch A, DPL \n"
|
|
" rlc A \n"
|
|
" djnz B, 00003$ \n"
|
|
" xch A, DPL \n"
|
|
" ret \n"
|
|
);
|
|
(void)val;
|
|
}
|
|
|
|
|
|
#pragma callee_saves mathPrvI16Asr1
|
|
int16_t mathPrvI16Asr1(int16_t val) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" mov A, DPH \n"
|
|
" mov C, A.7 \n"
|
|
" rrc A \n"
|
|
" mov DPH, A \n"
|
|
" mov A, DPL \n"
|
|
" rrc A \n"
|
|
" mov DPL, A \n"
|
|
" ret \n"
|
|
);
|
|
(void)val;
|
|
}
|
|
|
|
#pragma callee_saves mathPrvMul8x8
|
|
uint16_t mathPrvMul8x8(uint8_t a, uint8_t b) __reentrant __naked
|
|
{
|
|
//return expected in DPTR, first param is in DPL, second on stack
|
|
__asm__(
|
|
//grab param into B
|
|
" pop DPH \n\t"
|
|
" pop A \n\t"
|
|
" pop B \n\t"
|
|
" push B \n\t"
|
|
" push A \n\t"
|
|
" push DPH \n\t"
|
|
|
|
//second param into A
|
|
" mov A, DPL \n\t"
|
|
|
|
//do the deed
|
|
" mul AB \n\t"
|
|
|
|
//return results
|
|
" mov DPL, A \n\t"
|
|
" mov DPH, B \n\t"
|
|
|
|
" ret \n\t"
|
|
);
|
|
(void)a;
|
|
(void)b;
|
|
}
|
|
|
|
#pragma callee_saves mathPrvMul16x8
|
|
uint32_t mathPrvMul16x8(uint16_t a, uint8_t b) __reentrant __naked
|
|
{
|
|
//return expected in A:B:DPTR, first param is in DPTR, second on stack
|
|
__asm__(
|
|
//save r0
|
|
" push _R0 \n\t"
|
|
|
|
//get 2nd param into a & r0
|
|
" mov A, SP \n\t"
|
|
" add A, #-0x03 \n\t"
|
|
" mov R0, A \n\t"
|
|
" mov A, @R0 \n\t"
|
|
" mov R0, A \n\t"
|
|
|
|
//get first param.lo into B
|
|
" mov B, DPL \n\t"
|
|
|
|
//mul
|
|
" mul AB \n\t"
|
|
|
|
//lower result byte is ready!
|
|
" mov DPL, A \n\t"
|
|
|
|
//save upper in r0, get 2nd param into A
|
|
" mov A, R0 \n\t"
|
|
" mov R0, B \n\t"
|
|
|
|
//get first param.hi into B
|
|
" mov B, DPH \n\t"
|
|
|
|
//mul
|
|
" mul AB \n\t"
|
|
|
|
//add in the carry from before
|
|
" add A, R0 \n\t"
|
|
|
|
//produce middle byte
|
|
" mov DPH, A \n\t"
|
|
|
|
//calc high byte
|
|
" mov A, B \n\t"
|
|
" addc A, #0 \n\t"
|
|
" mov B, A \n\t"
|
|
|
|
//set high high byte to 0 (guaranteed)
|
|
" clr A \n\t"
|
|
|
|
//get out
|
|
" pop _R0 \n\t"
|
|
" ret \n\t"
|
|
);
|
|
(void)a;
|
|
(void)b;
|
|
}
|
|
|
|
#pragma callee_saves mathPrvMul32x8
|
|
uint32_t mathPrvMul32x8(uint32_t a, uint8_t b) __reentrant __naked
|
|
{
|
|
//return expected in A:B:DPTR, first param is in DPTR, second on stack
|
|
__asm__(
|
|
//save r0
|
|
" push _R0 \n\t"
|
|
" push _R1 \n\t"
|
|
|
|
//save A and B
|
|
" push A \n"
|
|
" push B \n"
|
|
|
|
//get second param into R0
|
|
" mov A, #-6 \n"
|
|
" add A, sp \n"
|
|
" mov R0, A \n"
|
|
" mov _R0, @R0 \n"
|
|
|
|
//low
|
|
" mov A, DPL \n"
|
|
" mov B, R0 \n"
|
|
" mul AB \n"
|
|
" mov DPL, A \n"
|
|
" mov R1, B \n"
|
|
|
|
//mid.lo
|
|
" mov A, DPH \n"
|
|
" mov B, R0 \n"
|
|
" mul AB \n"
|
|
" add A, R1 \n"
|
|
" mov DPH, A \n"
|
|
" mov A, B \n"
|
|
" addc A, #0 \n"
|
|
" mov R1, A \n"
|
|
|
|
//mid.hi
|
|
" pop A \n"
|
|
" mov B, R0 \n"
|
|
" mul AB \n"
|
|
" add A, R1 \n"
|
|
" xch A, B \n"
|
|
" addc A, #0 \n"
|
|
" mov R1, A \n"
|
|
|
|
//hi
|
|
" pop A \n"
|
|
" push B \n"
|
|
" mov B, R0 \n"
|
|
" mul AB \n"
|
|
" add A, R1 \n"
|
|
" pop B \n"
|
|
|
|
//get out
|
|
" pop _R1 \n\t"
|
|
" pop _R0 \n\t"
|
|
" ret \n\t"
|
|
);
|
|
(void)a;
|
|
(void)b;
|
|
}
|
|
|
|
#pragma callee_saves mathPrvMul16x16
|
|
uint32_t mathPrvMul16x16(uint16_t a, uint16_t b) __reentrant __naked
|
|
{
|
|
//return expected in A:B:DPTR, first param is in DPTR, second on stack (low byte was pushed first)
|
|
__asm__(
|
|
//save r0,r1,r2
|
|
" push _R0 \n\t"
|
|
" push _R1 \n\t"
|
|
" push _R2 \n\t"
|
|
|
|
//get 2nd param into r1:r0
|
|
" mov A, SP \n\t"
|
|
" add A, #-0x05 \n\t"
|
|
" mov R0, A \n\t"
|
|
" mov A, @R0 \n\t"
|
|
" mov R1, A \n\t"
|
|
" dec R0 \n\t"
|
|
" mov A, @R0 \n\t"
|
|
" mov R0, A \n\t"
|
|
|
|
//mul low bytes, save low result byte
|
|
" mov B, DPL \n\t"
|
|
" mul AB \n\t"
|
|
" push A \n\t"
|
|
|
|
//save high byte
|
|
" mov R2, B \n\t"
|
|
|
|
//mul p2.lo * p1.hi. add in high from the low multiplication. we know this fits in 16 bits!
|
|
" mov A, DPH \n\t"
|
|
" mov B, R0 \n\t"
|
|
" mul AB \n\t"
|
|
" add A, R2 \n\t"
|
|
" mov R0, A \n\t" //save intermediate's lo in R0
|
|
" mov A, B \n\t"
|
|
" addc A, #0 \n\t"
|
|
" mov R2, A \n\t" //save intermediate's hi in R2
|
|
|
|
//mul p2.hi * p1.lo, add in intermediate result
|
|
" mov A, R1 \n\t"
|
|
" mov B, DPL \n\t"
|
|
" mul AB \n\t"
|
|
" add A, R0 \n\t" //calc intermediate's lo
|
|
" push A \n\t" //push it
|
|
" mov A, B \n\t"
|
|
" addc A, R2 \n\t"
|
|
" mov R2, A \n\t" //calc intermediate's hi in R2
|
|
" mov A, #0 \n\t"
|
|
" addc A, #0 \n\t" //calc high byte so far
|
|
" mov R0, A \n\t" //store in R0
|
|
|
|
//mul high bytes
|
|
" mov A, R1 \n\t"
|
|
" mov B, DPH \n\t"
|
|
" mul AB \n\t"
|
|
" add A, R2 \n\t"
|
|
" mov R2, A \n\t" //final value for intermediate's high
|
|
" mov A, B \n\t"
|
|
" addc A, R0 \n\t" //final high value is ready
|
|
|
|
//produce the rest of the result bytes
|
|
" mov B, R2 \n\t"
|
|
" pop DPH \n\t"
|
|
" pop DPL \n\t"
|
|
|
|
//return
|
|
" pop _R2 \n\t"
|
|
" pop _R1 \n\t"
|
|
" pop _R0 \n\t"
|
|
" ret \n\t"
|
|
);
|
|
(void)a;
|
|
(void)b;
|
|
}
|
|
|
|
//pushes R0..R2, gets second param into r1:r0
|
|
#pragma callee_saves u64_start
|
|
static void u64_start(void) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" pop A \n" //get ret addr
|
|
" pop B \n" //get ret addr
|
|
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
" push _R2 \n"
|
|
|
|
" push B \n" //re-push ret addr
|
|
" push A \n"
|
|
|
|
" mov a, #0xf8 \n" // DPTR = pushed_arg
|
|
" add a, sp \n"
|
|
" mov R1, a \n"
|
|
" mov a, @R1 \n"
|
|
" mov R0, a \n"
|
|
" inc R1 \n"
|
|
" mov a, @R1 \n"
|
|
" mov R1, a \n"
|
|
|
|
" ret \n"
|
|
);
|
|
}
|
|
|
|
//jump to this, do not call it
|
|
//does not clobber anything
|
|
#pragma callee_saves u64_end
|
|
static void u64_end(void) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" pop _R2 \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
" ret \n"
|
|
);
|
|
}
|
|
|
|
#pragma callee_saves mathPrvSwapDptrR1R0
|
|
void mathPrvSwapDptrR1R0(void) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" xch A, R1 \n\t"
|
|
" xch A, DPH \n\t"
|
|
" xch A, R1 \n\t"
|
|
" xch A, R0 \n\t"
|
|
" xch A, DPL \n\t"
|
|
" xch A, R0 \n\t"
|
|
" ret \n\t"
|
|
);
|
|
}
|
|
|
|
#pragma callee_saves u64_copy
|
|
void u64_copy(uint64_t __xdata *dst, const uint64_t __xdata *src) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
|
|
" mov b, #8 \n" //repeat 8 times:
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx @dptr, a \n"
|
|
" inc dptr \n"
|
|
|
|
" djnz b, 00003$ \n"
|
|
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)dst;
|
|
(void)src;
|
|
}
|
|
|
|
void u64_copyFromCode(uint64_t __xdata *dst, const uint64_t __code *src) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
|
|
" mov b, #8 \n" //repeat 8 times:
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" clr a \n"
|
|
" movc a, @a+dptr \n"
|
|
" inc dptr \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx @dptr, a \n"
|
|
" inc dptr \n"
|
|
|
|
" djnz b, 00003$ \n"
|
|
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)dst;
|
|
(void)src;
|
|
}
|
|
|
|
#pragma callee_saves u64_add
|
|
void u64_add(uint64_t __xdata *lhsP, const uint64_t __xdata *rhsP) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
" clr C \n"
|
|
|
|
" mov b, #8 \n" //repeat 8 times:
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" mov _R2, a \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" addc a, R2 \n"
|
|
" movx @dptr, a \n"
|
|
" inc dptr \n"
|
|
|
|
" djnz b, 00003$ \n"
|
|
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)lhsP;
|
|
(void)rhsP;
|
|
}
|
|
|
|
#pragma callee_saves u64_and
|
|
void u64_and(uint64_t __xdata *lhsP, const uint64_t __xdata *rhsP) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
|
|
" mov b, #8 \n" //repeat 8 times:
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" mov _R2, a \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" anl a, R2 \n"
|
|
" movx @dptr, a \n"
|
|
" inc dptr \n"
|
|
|
|
" djnz b, 00003$ \n"
|
|
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)lhsP;
|
|
(void)rhsP;
|
|
}
|
|
|
|
#pragma callee_saves u64_sub
|
|
void u64_sub(uint64_t __xdata *lhsP, const uint64_t __xdata *rhsP) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
" clr C \n"
|
|
|
|
" mov b, #8 \n" //repeat 8 times:
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" mov _R2, a \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" subb a, R2 \n"
|
|
" movx @dptr, a \n"
|
|
" inc dptr \n"
|
|
|
|
" djnz b, 00003$ \n"
|
|
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)lhsP;
|
|
(void)rhsP;
|
|
}
|
|
|
|
#pragma callee_saves u64_isLt
|
|
__bit u64_isLt(const uint64_t __xdata *lhsP, const uint64_t __xdata *rhsP) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
" clr C \n"
|
|
|
|
" mov b, #8 \n" //repeat 8 times:
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" mov _R2, a \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" subb a, R2 \n"
|
|
|
|
" djnz b, 00003$ \n"
|
|
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)lhsP;
|
|
(void)rhsP;
|
|
}
|
|
|
|
#pragma callee_saves u64_isEq
|
|
__bit u64_isEq(const uint64_t __xdata *lhsP, const uint64_t __xdata *rhsP) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
|
|
" mov b, #8 \n" //repeat 8 times:
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" mov _R2, a \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" xrl a, R2 \n"
|
|
" jnz 00004$ \n"
|
|
" djnz b, 00003$ \n"
|
|
|
|
" setb C \n"
|
|
" ljmp _u64_end \n"
|
|
|
|
"00004$: \n"
|
|
" clr C \n"
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)lhsP;
|
|
(void)rhsP;
|
|
}
|
|
|
|
//c is set, A is what to add to each limb
|
|
#pragma callee_saves u64_incdec
|
|
static void u64_incdec(uint64_t __xdata *dst) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" xch A, R0 \n"
|
|
" push A \n"
|
|
" mov b, #8 \n" //repeat 8 times:
|
|
"00003$: \n"
|
|
" movx a, @dptr \n"
|
|
" addc a, R0 \n"
|
|
" movx @dptr, a \n"
|
|
" inc dptr \n"
|
|
" djnz b, 00003$ \n"
|
|
" pop _R0 \n"
|
|
" ret \n"
|
|
);
|
|
(void)dst;
|
|
}
|
|
|
|
#pragma callee_saves u64_inc
|
|
void u64_inc(uint64_t __xdata *dst) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" setb C \n"
|
|
" clr A \n"
|
|
" ljmp _u64_incdec \n"
|
|
);
|
|
(void)dst;
|
|
}
|
|
|
|
#pragma callee_saves u64_dec
|
|
void u64_dec(uint64_t __xdata *dst) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" clr C \n"
|
|
" mov A, #0xFF \n"
|
|
" ljmp _u64_incdec \n"
|
|
);
|
|
(void)dst;
|
|
}
|
|
|
|
|
|
#pragma callee_saves xMemSet
|
|
void xMemSet(void __xdata* mem, uint8_t val, uint16_t num) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
|
|
" mov A, #-6 \n"
|
|
" add A, sp \n"
|
|
" mov R0, A \n"
|
|
" mov A, @R0 \n" //num.lo
|
|
" mov B, A \n"
|
|
" inc R0 \n"
|
|
" mov _R1, @R0 \n" //num.hi
|
|
" orl A, R1 \n" //zero check
|
|
" jz 00002$ \n" //num is R1:B
|
|
" inc R0 \n"
|
|
" mov _R0, @R0 \n" //val
|
|
"00003$: \n"
|
|
" mov A, R0 \n"
|
|
" movx @DPTR, A \n"
|
|
" inc DPTR \n"
|
|
" mov A, #0xff \n"
|
|
" add A, B \n"
|
|
" mov B, A \n"
|
|
" mov A, #0xff \n"
|
|
" addc A, R1 \n"
|
|
" mov _R1, A \n"
|
|
" orl A, B \n"
|
|
" jnz 00003$ \n"
|
|
"00002$: \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
" ret \n"
|
|
);
|
|
|
|
(void)mem;
|
|
(void)val;
|
|
(void)num;
|
|
}
|
|
|
|
#pragma callee_saves xMemEqual
|
|
__bit xMemEqual(const void __xdata* memA, const void __xdata* memB, uint8_t num) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
" push _R2 \n"
|
|
|
|
" mov a, #-7 \n"
|
|
" add a, sp \n"
|
|
" mov R1, a \n"
|
|
" mov A, @R1 \n"
|
|
" setb C \n" //equal if len is zero
|
|
" jz 00004$ \n"
|
|
" mov B, A \n"
|
|
" inc R1 \n"
|
|
" mov _R0, @R1 \n"
|
|
" inc R1 \n"
|
|
" mov _R1, @R1 \n"
|
|
" clr C \n"
|
|
"00003$: \n"
|
|
" movx a, @dptr \n"
|
|
" mov _R2, a \n"
|
|
" inc dptr \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" xrl a, R2 \n"
|
|
" jnz 00004$ \n"
|
|
" djnz b, 00003$ \n"
|
|
" setb C \n"
|
|
"00004$: \n"
|
|
" pop _R2 \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
" ret \n"
|
|
);
|
|
|
|
(void)memA;
|
|
(void)memB;
|
|
(void)num;
|
|
}
|
|
|
|
#pragma callee_saves xMemCopy
|
|
void xMemCopy(void __xdata* dst, const void __xdata* src, uint16_t num) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
" push _R2 \n"
|
|
|
|
" mov A, #-8 \n"
|
|
" add A, sp \n"
|
|
" mov R1, A \n"
|
|
" mov A, @R1 \n"
|
|
" mov B, A \n"
|
|
" inc R1 \n"
|
|
" mov _R2, @R1 \n" //R2:B is length
|
|
" orl A, R2 \n"
|
|
" jz 00004$ \n" //handle zero length
|
|
" inc R1 \n"
|
|
" mov _R0, @R1 \n"
|
|
" inc R1 \n"
|
|
" mov _R1, @R1 \n" //R1:R0 is src
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx @DPTR, A \n"
|
|
" inc DPTR \n"
|
|
" mov A, #0xff \n"
|
|
" add A, B \n"
|
|
" mov B, A \n"
|
|
" mov A, #0xff \n"
|
|
" addc A, R2 \n"
|
|
" mov _R2, A \n"
|
|
" orl A, B \n"
|
|
" jnz 00003$ \n"
|
|
"00004$: \n"
|
|
" pop _R2 \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
" ret \n"
|
|
);
|
|
|
|
(void)dst;
|
|
(void)src;
|
|
(void)num;
|
|
}
|
|
|
|
#pragma callee_saves xMemCopyShort
|
|
void xMemCopyShort(void __xdata* dst, const void __xdata* src, uint8_t num) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
" push _R2 \n"
|
|
|
|
" mov a, #-7 \n"
|
|
" add a, sp \n"
|
|
" mov R1, a \n"
|
|
" mov A, @R1 \n"
|
|
" jz 00004$ \n"
|
|
" mov B, A \n"
|
|
" inc R1 \n"
|
|
" mov _R0, @R1 \n"
|
|
" inc R1 \n"
|
|
" mov _R1, @R1 \n"
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx @dptr, a \n"
|
|
" inc dptr \n"
|
|
" djnz b, 00003$ \n"
|
|
"00004$: \n"
|
|
" pop _R2 \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
" ret \n"
|
|
);
|
|
|
|
(void)dst;
|
|
(void)src;
|
|
(void)num;
|
|
}
|
|
|
|
#pragma callee_saves xStrLen
|
|
uint16_t xStrLen(const char __xdata *str) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" push DPH \n"
|
|
" push DPL \n"
|
|
"00003$: \n"
|
|
" movx a, @dptr \n"
|
|
" jz 00002$ \n"
|
|
" inc dptr \n"
|
|
" sjmp 00003$ \n"
|
|
"00002$: \n"
|
|
" clr C \n"
|
|
" mov A, DPL \n"
|
|
" pop B \n"
|
|
" subb A, B \n"
|
|
" mov DPL, A \n"
|
|
" mov A, DPH \n"
|
|
" pop B \n"
|
|
" subb A, B \n"
|
|
" mov DPH, A \n"
|
|
" ret \n"
|
|
);
|
|
|
|
(void)str;
|
|
}
|
|
|
|
#pragma callee_saves static mathPrvDivMod32x16
|
|
static uint32_t mathPrvDivMod32x16(uint32_t num, uint16_t denom) __reentrant __naked
|
|
{
|
|
//PSW.5 determines if to produce quotient (0) or remainder(1)
|
|
|
|
__asm__(
|
|
" push _R3 \n"
|
|
" push _R2 \n"
|
|
" push _R1 \n"
|
|
" push _R0 \n"
|
|
" push A \n"
|
|
" push B \n"
|
|
" push DPH \n"
|
|
" push DPL \n"
|
|
" mov R1, sp \n" //R1: point to bottom byte of numerator
|
|
|
|
//get denom -> B:R0
|
|
" mov A, #-10 \n"
|
|
" add A, sp \n"
|
|
" mov R0, A \n" //R0 = &denom.hi
|
|
" mov B, @R0 \n" //B = denom.hi
|
|
" dec R0 \n"
|
|
" mov _R0, @R0 \n" //R0 = denom.lo
|
|
|
|
//shift it off (in B:R0), record how many iters we'll need (in DPL), generate proper top 8 bits for result mask (in R3:R2)
|
|
" mov _R2, #1 \n"
|
|
" mov _R3, #0 \n"
|
|
" mov DPL, #17 \n"
|
|
"00002$: \n"
|
|
" mov C, B.7 \n"
|
|
" jc 00003$ \n"
|
|
|
|
" clr C \n"
|
|
" mov A, R0 \n"
|
|
" rlc A \n"
|
|
" mov R0, A \n"
|
|
" mov A, B \n"
|
|
" rlc A \n"
|
|
" mov B, A \n"
|
|
|
|
" clr C \n"
|
|
" mov A, R2 \n"
|
|
" rlc A \n"
|
|
" mov R2, A \n"
|
|
" mov A, R3 \n"
|
|
" rlc A \n"
|
|
" mov R3, A \n"
|
|
|
|
" inc DPL \n"
|
|
" sjmp 00002$ \n"
|
|
"00003$: \n"
|
|
|
|
" clr A \n"
|
|
|
|
//push result_mask to stack
|
|
" push _R3 \n"
|
|
" push _R2 \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" mov R2, sp \n" //R2: point to bottom byte of result_mask
|
|
|
|
//push denom.shifted to stack
|
|
" push B \n"
|
|
" push _R0 \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" mov R0, sp \n" //R0: point to bottom byte of denom.shifted
|
|
|
|
//push result to stack
|
|
" push A \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" mov R3, sp \n" //R3: point to bottom byte of result
|
|
|
|
//loop-divide
|
|
"00088$: \n"
|
|
|
|
// check if denom.shifted >= num
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
" clr C \n"
|
|
" mov DPH, #4 \n"
|
|
"00001$: \n"
|
|
" mov B, @R0 \n"
|
|
" dec R0 \n"
|
|
" mov A, @R1 \n"
|
|
" dec R1 \n"
|
|
" subb A, B \n"
|
|
" djnz DPH, 00001$ \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
" jc 00099$ \n" //no? skip this round
|
|
|
|
//subtract
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
" clr C \n"
|
|
" mov DPH, #4 \n"
|
|
"00004$: \n"
|
|
" mov B, @R0 \n"
|
|
" dec R0 \n"
|
|
" mov A, @R1 \n"
|
|
" subb A, B \n"
|
|
" mov @R1, A \n"
|
|
" dec R1 \n"
|
|
" djnz DPH, 00004$ \n"
|
|
//keep r0 & r1 pushed
|
|
|
|
//set bit in result
|
|
//r0 & r1 still pushed
|
|
" mov _R0, _R2 \n"
|
|
" mov _R1, _R3 \n"
|
|
" mov DPH, #4 \n"
|
|
"00005$: \n"
|
|
" mov B, @R0 \n"
|
|
" dec R0 \n"
|
|
" mov A, @R1 \n"
|
|
" orl A, B \n"
|
|
" mov @R1, A \n"
|
|
" dec R1 \n"
|
|
" djnz DPH, 00005$ \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
|
|
//set up next iteration
|
|
"00099$: \n"
|
|
|
|
// shift denom right one (pointer ends up where needed)
|
|
" mov A, #0xfc \n"
|
|
" add A, R0 \n"
|
|
" mov R0, A \n"
|
|
" clr C \n"
|
|
" mov DPH, #4 \n"
|
|
"00006$: \n"
|
|
" inc R0 \n"
|
|
" mov A, @R0 \n"
|
|
" rrc A \n"
|
|
" mov @R0, A \n"
|
|
" djnz DPH, 00006$ \n"
|
|
|
|
// shift result mask right one
|
|
" push _R0 \n"
|
|
" mov A, #0xfc \n"
|
|
" add A, R2 \n"
|
|
" mov R0, A \n"
|
|
" clr C \n"
|
|
" mov DPH, #4 \n"
|
|
"00007$: \n"
|
|
" inc R0 \n"
|
|
" mov A, @R0 \n"
|
|
" rrc A \n"
|
|
" mov @R0, A \n"
|
|
" djnz DPH, 00007$ \n"
|
|
" pop _R0 \n"
|
|
|
|
//check on loop limit
|
|
" djnz DPL, 00088$ \n"
|
|
|
|
//we're done. undo the terrible things we've done to the stack and get the result
|
|
|
|
//quotient return?
|
|
" jb PSW.5, 00009$ \n"
|
|
//return quotient
|
|
" pop DPL \n"
|
|
" pop DPH \n"
|
|
" pop B \n"
|
|
" pop _R0 \n"
|
|
"00009$: \n"
|
|
|
|
//now clear up the rest
|
|
" mov A, #-12 \n"
|
|
" add A, sp \n"
|
|
" mov sp, A \n"
|
|
|
|
//remainder return?
|
|
" jnb PSW.5, 00010$ \n"
|
|
//return quotient
|
|
" pop DPL \n"
|
|
" pop DPH \n"
|
|
" pop B \n"
|
|
" pop _R0 \n"
|
|
"00010$: \n"
|
|
|
|
" mov A, R0 \n"
|
|
|
|
//pop off regs
|
|
" pop _R0 \n"
|
|
" pop _R1 \n"
|
|
" pop _R2 \n"
|
|
" pop _R3 \n"
|
|
|
|
" ret \n"
|
|
|
|
);
|
|
|
|
(void)num;
|
|
(void)denom;
|
|
}
|
|
|
|
#pragma callee_saves static mathPrvDiv32x16
|
|
uint32_t mathPrvDiv32x16(uint32_t num, uint16_t denom) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" clr PSW.5 \n"
|
|
" ljmp _mathPrvDivMod32x16 \n"
|
|
);
|
|
|
|
(void)num;
|
|
(void)denom;
|
|
}
|
|
|
|
#pragma callee_saves static mathPrvDiv32x16
|
|
uint16_t mathPrvMod32x16(uint32_t num, uint16_t denom) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" setb PSW.5 \n"
|
|
" ljmp _mathPrvDivMod32x16 \n"
|
|
);
|
|
|
|
(void)num;
|
|
(void)denom;
|
|
}
|
|
|
|
#pragma callee_saves mathPrvDiv32x8
|
|
uint32_t mathPrvDiv32x8(uint32_t num, uint8_t denom) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" push _R3 \n"
|
|
" push _R2 \n"
|
|
" push _R1 \n"
|
|
" push _R0 \n"
|
|
" push A \n"
|
|
" push B \n"
|
|
" push DPH \n"
|
|
" push DPL \n"
|
|
" mov R1, sp \n" //R1: point to bottom byte of numerator
|
|
|
|
//get denom -> B
|
|
" mov A, #0xf6 \n"
|
|
" add A, sp \n"
|
|
" mov R0, A \n"
|
|
" mov B, @R0 \n"
|
|
|
|
//shift it off (in B), record how many iters we'll need (in DPL), generate proper top 8 bits for result mask (in A)
|
|
" mov A, #1 \n"
|
|
" mov DPL, #25 \n"
|
|
"00002$: \n"
|
|
" mov C, B.7 \n"
|
|
" jc 00003$ \n"
|
|
" rl A \n"
|
|
" xch A, B \n"
|
|
" rl A \n"
|
|
" xch A, B \n"
|
|
" inc DPL \n"
|
|
" sjmp 00002$ \n"
|
|
"00003$: \n"
|
|
|
|
//push result_mask to stack
|
|
" push A \n"
|
|
" clr A \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" mov R2, sp \n" //R2: point to bottom byte of result_mask
|
|
|
|
//push denom.shifted to stack
|
|
" push B \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" mov R0, sp \n" //R0: point to bottom byte of denom.shifted
|
|
|
|
//push result to stack
|
|
" push A \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" push A \n"
|
|
" mov R3, sp \n" //R3: point to bottom byte of result
|
|
|
|
//loop-divide
|
|
"00088$: \n"
|
|
|
|
// check if denom.shifted >= num
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
" clr C \n"
|
|
" mov DPH, #4 \n"
|
|
"00001$: \n"
|
|
" mov B, @R0 \n"
|
|
" dec R0 \n"
|
|
" mov A, @R1 \n"
|
|
" dec R1 \n"
|
|
" subb A, B \n"
|
|
" djnz DPH, 00001$ \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
" jc 00099$ \n" //no? skip this round
|
|
|
|
//subtract
|
|
" push _R0 \n"
|
|
" push _R1 \n"
|
|
" clr C \n"
|
|
" mov DPH, #4 \n"
|
|
"00004$: \n"
|
|
" mov B, @R0 \n"
|
|
" dec R0 \n"
|
|
" mov A, @R1 \n"
|
|
" subb A, B \n"
|
|
" mov @R1, A \n"
|
|
" dec R1 \n"
|
|
" djnz DPH, 00004$ \n"
|
|
//keep r0 & r1 pushed
|
|
|
|
//set bit in result
|
|
//r0 & r1 still pushed
|
|
" mov _R0, _R2 \n"
|
|
" mov _R1, _R3 \n"
|
|
" mov DPH, #4 \n"
|
|
"00005$: \n"
|
|
" mov B, @R0 \n"
|
|
" dec R0 \n"
|
|
" mov A, @R1 \n"
|
|
" orl A, B \n"
|
|
" mov @R1, A \n"
|
|
" dec R1 \n"
|
|
" djnz DPH, 00005$ \n"
|
|
" pop _R1 \n"
|
|
" pop _R0 \n"
|
|
|
|
//set up next iteration
|
|
"00099$: \n"
|
|
|
|
// shift denom right one (pointer ends up where needed)
|
|
" mov A, #0xfc \n"
|
|
" add A, R0 \n"
|
|
" mov R0, A \n"
|
|
" clr C \n"
|
|
" mov DPH, #4 \n"
|
|
"00006$: \n"
|
|
" inc R0 \n"
|
|
" mov A, @R0 \n"
|
|
" rrc A \n"
|
|
" mov @R0, A \n"
|
|
" djnz DPH, 00006$ \n"
|
|
|
|
// shift result mask right one
|
|
" push _R0 \n"
|
|
" mov A, #0xfc \n"
|
|
" add A, R2 \n"
|
|
" mov R0, A \n"
|
|
" clr C \n"
|
|
" mov DPH, #4 \n"
|
|
"00007$: \n"
|
|
" inc R0 \n"
|
|
" mov A, @R0 \n"
|
|
" rrc A \n"
|
|
" mov @R0, A \n"
|
|
" djnz DPH, 00007$ \n"
|
|
" pop _R0 \n"
|
|
|
|
//check on loop limit
|
|
" djnz DPL, 00088$ \n"
|
|
|
|
//we're done. undo the terrible things we've done to the stack
|
|
|
|
//first, get the result
|
|
" pop DPL \n"
|
|
" pop DPH \n"
|
|
" pop B \n"
|
|
" pop _R0 \n"
|
|
|
|
//now clear up the rest
|
|
" mov A, #-12 \n"
|
|
" add A, sp \n"
|
|
" mov sp, A \n"
|
|
|
|
" mov A, R0 \n"
|
|
|
|
//pop off regs
|
|
" pop _R0 \n"
|
|
" pop _R1 \n"
|
|
" pop _R2 \n"
|
|
" pop _R3 \n"
|
|
|
|
" ret \n"
|
|
);
|
|
|
|
(void)num;
|
|
(void)denom;
|
|
}
|
|
|
|
#pragma callee_saves mathPrvDivMod16x8
|
|
static uint16_t mathPrvDivMod16x8(uint16_t num, uint8_t denom) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" push _R6 \n"
|
|
" push _R5 \n"
|
|
" push _R4 \n"
|
|
" push _R3 \n"
|
|
" push _R2 \n"
|
|
" push _R1 \n"
|
|
" push _R0 \n"
|
|
|
|
//get denom -> B
|
|
" mov A, #-9 \n"
|
|
" add A, sp \n"
|
|
" mov R0, A \n"
|
|
" mov B, @R0 \n"
|
|
|
|
//shift it off (in B), record how many iters we'll need (in R4), generate proper top 8 bits for result mask (in A)
|
|
" mov A, #1 \n"
|
|
" mov R4, #9 \n"
|
|
"00002$: \n"
|
|
" mov C, B.7 \n"
|
|
" jc 00003$ \n"
|
|
" rl A \n"
|
|
" xch A, B \n"
|
|
" rl A \n"
|
|
" xch A, B \n"
|
|
" inc R4 \n"
|
|
" sjmp 00002$ \n"
|
|
"00003$: \n"
|
|
|
|
//result mask in R3:R2 \n"
|
|
" mov R3, A \n"
|
|
" clr A \n"
|
|
" mov R2, A \n"
|
|
|
|
//quotient in R1:R0 \n"
|
|
" mov R1, B \n"
|
|
" mov R0, A \n"
|
|
|
|
//iter count in B \n"
|
|
" mov B, DPL \n"
|
|
|
|
//result in R6:R5
|
|
" mov R5, A \n"
|
|
" mov R6, A \n"
|
|
|
|
//loop-divide
|
|
"00088$: \n"
|
|
|
|
// check if denom.shifted >= num
|
|
" clr C \n"
|
|
" mov A, DPL \n"
|
|
" subb A, R0 \n"
|
|
" mov A, DPH \n"
|
|
" subb A, R1 \n"
|
|
" jc 00099$ \n" //no? skip this round
|
|
|
|
//subtract
|
|
" clr C \n"
|
|
" mov A, DPL \n"
|
|
" subb A, R0 \n"
|
|
" mov DPL, A \n"
|
|
" mov A, DPH \n"
|
|
" subb A, R1 \n"
|
|
" mov DPH, A \n"
|
|
|
|
//set bit in result
|
|
" mov A, R2 \n"
|
|
" orl A, R5 \n"
|
|
" mov R5, A \n"
|
|
" mov A, R3 \n"
|
|
" orl A, R6 \n"
|
|
" mov R6, A \n"
|
|
|
|
//set up next iteration
|
|
"00099$: \n"
|
|
|
|
// shift denom right one
|
|
" clr C \n"
|
|
" mov A, R1 \n"
|
|
" rrc A \n"
|
|
" mov R1, A \n"
|
|
" mov A, R0 \n"
|
|
" rrc A \n"
|
|
" mov R0, A \n"
|
|
|
|
// shift result mask right one
|
|
" clr C \n"
|
|
" mov A, R3 \n"
|
|
" rrc A \n"
|
|
" mov R3, A \n"
|
|
" mov A, R2 \n"
|
|
" rrc A \n"
|
|
" mov R2, A \n"
|
|
|
|
//check on loop limit
|
|
" djnz R4, 00088$ \n"
|
|
|
|
//we're done - produce the result (it is already in DPT Rif we want modulus)
|
|
" jb PSW.5, 00098$ \n"
|
|
" mov DPL, R5 \n"
|
|
" mov DPH, R6 \n"
|
|
"00098$: \n"
|
|
|
|
//pop off regs
|
|
" pop _R0 \n"
|
|
" pop _R1 \n"
|
|
" pop _R2 \n"
|
|
" pop _R3 \n"
|
|
" pop _R4 \n"
|
|
" pop _R5 \n"
|
|
" pop _R6 \n"
|
|
|
|
" ret \n"
|
|
);
|
|
|
|
(void)num;
|
|
(void)denom;
|
|
}
|
|
|
|
#pragma callee_saves mathPrvDiv16x8
|
|
uint16_t mathPrvDiv16x8(uint16_t num, uint8_t denom) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" clr PSW.5 \n"
|
|
" ljmp _mathPrvDivMod16x8 \n"
|
|
);
|
|
|
|
(void)num;
|
|
(void)denom;
|
|
}
|
|
|
|
#pragma callee_saves mathPrvMod16x8
|
|
uint8_t mathPrvMod16x8(uint16_t num, uint8_t denom) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" setb PSW.5 \n"
|
|
" ljmp _mathPrvDivMod16x8 \n"
|
|
);
|
|
|
|
(void)num;
|
|
(void)denom;
|
|
}
|
|
|
|
char charsPrvDerefAndIncGenericPtr(const char * __xdata* __xdata str) __naked
|
|
{
|
|
__asm__(
|
|
" movx A, @DPTR \n"
|
|
" push A \n"
|
|
" add A, #1 \n"
|
|
" movx @DPTR, A \n"
|
|
" inc DPTR \n"
|
|
" movx A, @DPTR \n"
|
|
" push A \n"
|
|
" addc A, #0 \n"
|
|
" movx @DPTR, A \n"
|
|
" inc DPTR \n"
|
|
" movx A, @DPTR \n"
|
|
" pop _DPH \n"
|
|
" pop _DPL \n"
|
|
" jz 00001$ \n" //check for xdata, taken if yes
|
|
" cjne A, #0x60, 00002$ \n" //check for pdata, taken if no
|
|
|
|
//pdata
|
|
" push _R0 \n"
|
|
" mov R0, DPL \n"
|
|
" movx A, @R0 \n"
|
|
" pop _R0 \n"
|
|
" mov DPL, A \n"
|
|
" ret \n"
|
|
|
|
"00002$: \n"
|
|
" jc 00003$ \n" //check for idata. taken if yes
|
|
|
|
//code
|
|
" clr A \n"
|
|
" movc A, @A+DPTR \n"
|
|
" mov DPL, A \n"
|
|
" ret \n"
|
|
|
|
//xdata
|
|
"00001$: \n"
|
|
" movx A, @DPTR \n"
|
|
" mov DPL, A \n"
|
|
" ret \n"
|
|
|
|
//idata
|
|
"00003$: \n"
|
|
" push _R0 \n"
|
|
" mov R0, DPL \n"
|
|
" mov A, @R0 \n"
|
|
" pop _R0 \n"
|
|
" mov DPL, A \n"
|
|
" ret \n"
|
|
);
|
|
|
|
(void)str;
|
|
}
|
|
|
|
void mathPrvCopyPostinc(uint32_t __xdata *dst, uint32_t __xdata *src) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
|
|
" mov b, #4 \n" //repeat 4 times:
|
|
" setb C \n"
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" mov r2, a \n"
|
|
" addc a, #0 \n"
|
|
" movx @dptr, a \n"
|
|
" mov a, r2 \n"
|
|
" inc dptr \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx @dptr, a \n"
|
|
" inc dptr \n"
|
|
|
|
" djnz b, 00003$ \n"
|
|
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)dst;
|
|
(void)src;
|
|
}
|
|
|
|
__bit xMemEqual4(const void __xdata* memA, const void __xdata* memB) __reentrant __naked
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n" //get second pointer into R1:R0
|
|
" mov b, #4 \n" //repeat 4 times:
|
|
" clr C \n"
|
|
"00003$: \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" mov r2, a \n"
|
|
" inc dptr \n"
|
|
" lcall _mathPrvSwapDptrR1R0 \n"
|
|
" movx a, @dptr \n"
|
|
" inc dptr \n"
|
|
" xrl a, r2 \n"
|
|
" jnz 00004$ \n"
|
|
" djnz b, 00003$ \n"
|
|
" setb C \n"
|
|
"00004$: \n"
|
|
|
|
" ljmp _u64_end \n"
|
|
);
|
|
|
|
(void)memA;
|
|
(void)memB;
|
|
}
|
|
|
|
__bit u32minusU16(uint32_t __xdata *u32, uint16_t u16) __naked __reentrant
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n"
|
|
" clr C \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" subb A, R0 \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" subb A, R1 \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" subb A, #0 \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" subb A, #0 \n"
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)u32;
|
|
(void)u16;
|
|
}
|
|
|
|
__bit u32plusU16(uint32_t __xdata *u32, uint16_t u16) __naked __reentrant
|
|
{
|
|
__asm__(
|
|
" lcall _u64_start \n"
|
|
" clr C \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" addc A, R0 \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" addc A, R1 \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" addc A, #0 \n"
|
|
" movx A, @DPTR \n"
|
|
" inc DPTR \n"
|
|
" addc A, #0 \n"
|
|
" ljmp _u64_end \n"
|
|
);
|
|
(void)u32;
|
|
(void)u16;
|
|
}
|
|
|
|
uint8_t u32Nonzero(uint32_t __xdata *u32) __naked __reentrant
|
|
{
|
|
__asm__(
|
|
" mov B, #4 \n"
|
|
"00001$: \n"
|
|
" movx A, @DPTR \n"
|
|
" jnz 00002$ \n"
|
|
" inc DPTR \n"
|
|
" djnz B, 00001$ \n"
|
|
"00002$: \n"
|
|
" mov DPL, A \n"
|
|
" ret \n"
|
|
);
|
|
(void)u32;
|
|
}
|
|
|
|
__bit i32Negative(uint32_t __xdata *u32) __naked __reentrant
|
|
{
|
|
__asm__(
|
|
" inc DPTR \n"
|
|
" inc DPTR \n"
|
|
" inc DPTR \n"
|
|
" movx A, @DPTR \n"
|
|
" rlc A \n"
|
|
" ret \n"
|
|
);
|
|
(void)u32;
|
|
}
|
|
|
|
|