Jerry Messina wrote: ↑Wed Sep 07, 2022 11:06 am
If there's anything else you care to share we'll be doing an update soon to add the "const data at address" feature, so now's a good time.
That depends on how big changes are you willing to make
. More seriously, as I doubted you'd be making any, I stopped mimicking present internal math routines so my library is not a simple replacement. To tell the truth, I got a bit carried away and, exploiting the possibilities of SF macros, I've added even more detailed routines, like 16x8 and 32x8 bit multiplication. And, besides diagnostic flags, an exception mechanism that forces program to jump to a predetermined place in case of error
.
Anyway, I can share the whole library and help in adjusting what you find applicable if you agree at least to preserve the diagnostic option (as an option, i.e. activated with appropriate define). SF already uses internal variable in floating-point routines so I used the same byte for statuses (last three bits are prepared to accommodate my version of floating-point math lib and may be skipped).
Code: Select all
dim FM_stat as D24 // math statuses
const
_FM_IOV=0,
_FM_FOV=1,
_FM_FDZ=2,
_FM_NAN=3,
_FM_DOM=4,
_FM_FUN=5,
_FM_RND=6,
_FM_SAT=7
Note that to reduce code I have most of signed routines using the unsigned ones, like
Code: Select all
//-------------- Division, 8-bit unsigned
// Input: D0, D4 (D13)
// Output: D0, remainder in D8
// Uses: D12, D13
// D13 bits: 0 - result to be negated
// 2 - remainder to be negated (negative dividend)
// 7 - signed division
public sub Div_8x8_U()
asm-
CLRF D13 // unsigned
// entry for signed division
CLRF D8
MOVF D4,F // divisor is zero?
BNZ Div_8x8_UL1 // ...no
MOVF D0,F // dividend is zero, as well?
end asm
#ifdef FM_FLAGS
asm-
BTFSC STATUS,Z
BSF FM_stat,_FM_NAN// ...yes, set NAN flag
BZ $+6
BSF FM_stat,_FM_FDZ// ...no, set FDZ flag
BSF FM_stat,_FM_FOV
end asm
#endif
asm-
MOVLW 0x7F // set max value according
BTFSC D13,2 // to sign of dividend, if signed
MOVLW 0x80
BTFSS D13,7 // or to FF, if unsigned
MOVLW 0xFF
MOVWF D0
end asm
#ifdef FM_EXCEPTIONS
asm-
goto GoFMerror
end asm
#else
asm-
RETURN
end asm
#endif
asm-
Div_8x8_UL1:
MOVF D0,W // dividend is zero?
BTFSC STATUS,Z
RETLW 0
MOVLW 8 // actual division
MOVWF D12
RLCF D0,W
RLCF D8,F
MOVF D4,W
SUBWF D8,F
BC $+6
ADDWF D8,F
BCF STATUS,C
RLCF D0,F
DECFSZ D12,F
BRA $-18
BTFSS D13,7 // signed?
RETURN // ...no
BTFSC D13,2 // remainder supposed to be negative?
NEGF D8
BTFSS D13,0 // result supposed to be negative?
BRA $+6
NEGF D0
RETURN
BTFSS D0,7 // overflow (-128/-1)?
RETURN
DECF D0,F // ...yes, set max positive value
// (remainder is zero)
end asm
#ifdef FM_FLAGS
asm-
BSF FM_stat,_FM_IOV// ...set IOV flag
end asm
#endif
#ifdef FM_EXCEPTIONS
asm-
goto GoFMerror
end asm
#endif
end sub {Div_8x8_U}
//-------------- Division, 8-bit signed (short)
// Input: D0, D4
// Output: D0, remainder in D8
// Uses: D12, D13
// D13 bits: 0 - result to be negated
// 2 - remainder to be negated (negative dividend)
// 7 - signed division
public sub Div_8x8_S()
asm-
CLRF D13
BSF D13,7
BTFSS D0,7 // negative dividend?
BRA $+8
NEGF D0
INCF D13,F
BSF D13,2 // ...yes, remainder to be negated
BTFSS D4,7 // negative divisor?
BRA $+6
NEGF D4
INCF D13,F // if D13.0=1 then result to be negated
goto Div_8x8_U+2
end asm
BEGIN_SB_COMMENT_BLOCK() // force compiler to include Div_16x16_U
addressof(Div_8x8_U)
END_SB_COMMENT_BLOCK()
end sub {Div_8x8_S}