PDA

View Full Version : HELP WITH SOME Nbit MATH



longpole001
- 23rd March 2016, 15:31
HI guys ,
i have been trying to get N-BIT Math equivalent equation to the following commands
if A_32bit < B_32bit then
B_32bit = A_32bit
PBP_X = PBP_Y
endif

if A_32bit> C_32bit then
C_32bit = A_32bit
PBP_X = PBP_Z
endif


N bit math allows for compare command using DT wraper (@ MATH_CMP _A, _B ; Compare Pvars - result in M_EQ and M_GTE bits)
this actually means
"M_CMP Z <=> X -> STATUS Compare registers Z and X. Comparison results are returned in the STATUS register. If register Z==X, the Z-bit of the STATUS register is set. If register Z=>X, the C-bit of the STATUS register is set.


looking at the notes on the command
http://avtanski.net/projects/math/
http://www.picbasic.co.uk/forum/showthread.php?t=12433

in this example there is mix of 32 nbit Nmath varables that then if true select PBP varables

i can not see a lessthan (<) option in this description of equation and its not clear how i can use the result to then do further work to the PBP varables in the above equation as yet

some help on how to get the compare command to do the above would be great

Cheers

Sheldon

pedja089
- 23rd March 2016, 15:55
Look at this:

MATH_CMP macro Zin, Xin ; Compare Pvars - result in M_EQ and M_GTE bits
MOVE?PP Zin, REG_Z ; Z <=> X -> STATUS(C,Z)
MOVE?PP Xin, REG_X
CLRFSR ; clear FSR first
L?CALL M_CMP
MOVE?TT STATUS,Z, _M_EQ ; STATUS,Z set if Z == X
MOVE?TT STATUS,C, _M_GTE ; STATUS,C set if Z => X;
endm
If I understand Darrel's code then:

If Z and X are equal you have set M_EQ and M_GTE
If Z is greater than X, bit M_GTE is set, bit M_EQ is 0
If Z is less than X, M_GTE and M_EQ are 0

EDIT:
PBP code should look like this:
IF M_EQ=1 AND M_GTE=1 THEN
'Z = X
ELSEIF M_EQ=0 AND M_GTE=1 THEN
'Z > X
ELSE 'M_EQ=0 AND M_GTE=0
'Z < X
ENDIF

longpole001
- 23rd March 2016, 17:37
thanks that make a bit more sense to me now

i had only used the M_GTE flag = 0 for < values
and M_GTE_flag = 1 for > values


@ MATH_CMP _Result_32bit , _Slow_Sublap_32bit ' Compare Pvars - result in M_EQ and M_GTE bits - if sublap result < slow_sublap then slow_sublap = sublap resutl
@ MOVE?PB _M_GTE, _glc_s ' get result of compare ( Z=>X) into a tmp PBP byte
if glc_s = 0 then ' if result is 0 then compare sublap < slow_sublap = true
@ MOVE?PP _Result_32bit , _Slow_Sublap_32bit ' copy the sublap time to slow_sublap time
etc ......

which is not correct i think

i am using the nmath for time to sort out fastest , slowest times from a record
each record shows time value for each lap

base method is
tmp0 = 0
slowlap = 0
fastlap = 0

loop:
get a lap time & its record ref
convert time to secs_result
secs_result - tmp0 ' to get lap time in sec
tmp0 = secs_result ' copy last time into tmp for next loop
if sec_result < slowlap then
slowlap = sec_result
store other pbp records
endif

if sec_result > fastlap then
fastlap = sec_result
store other pbp records
endif
endloop

pedja089
- 23rd March 2016, 19:20
You are over complicated this

@ MOVE?PB _M_GTE, _glc_s ' get result of compare ( Z=>X) into a tmp PBP byte THIS IS NOT CORRECT!!!
if glc_s = 0 then ' if result is 0 then compare sublap < slow_sublap = true

Look at lines 25 and 26 of DT's include:

M_EQ VAR BIT ; Equal to, for CMP
M_GTE VAR BIT ; Greater than or Equal to, for CMP
M_GTE and M_EQ are PBP variables(bit).
So you don't need to copy them or what ever MOVE?PB will do to bit. Just use it as any variable in pbp.
Look at my example, and use it that way to make life little bit easier :)
EDIT (again):
Look at lines 201 and 202

MOVE?TT STATUS,Z, _M_EQ ; STATUS,Z set if Z == X
MOVE?TT STATUS,C, _M_GTE ; STATUS,C set if Z => X;
They move results from PIC STATUS register to bit defined at line 25 and 26.

longpole001
- 23rd March 2016, 23:17
ok thanks pedja , it was 2am when i was writting this code

cheers

sheldon

longpole001
- 24th March 2016, 08:45
by the way i found the Nmath does not like array varables eg @MOVE?BP _ARRAY[1] , TMP_32BIT ' copy value in array into tmp nmath var

well that section is done i think, but now i want to do an avg lap time and return the values from sec into day/hours/min/sec

i have total secs for event / laps completed = sec per lap ( 32bit result + remainder)

now need to get it back in to sec , min, hours/ days using nmath

pedja089
- 24th March 2016, 08:53
This is ASM code:

@MOVE?BP _ARRAY[1] , TMP_32BIT
In ASM arrays are not defined. Instead of defining each byte or word or long of array ASM use base address(like _Array) and offset.
So if your array is byte I think that you can do it like this for array[1]

@MOVE?BP _ARRAY+1 , TMP_32BIT
'TMP_32BIT=Array[2]
@MOVE?BP _ARRAY+2 , TMP_32BIT
For word

TMP_32BIT=Array[1]
@MOVE?WP _ARRAY+2 , TMP_32BIT
TMP_32BIT=Array[2]
@MOVE?WP _ARRAY+4 , TMP_32BIT ;Because each word in array uses 2 bytes, you increase index by 2.
For long index are 4,8 etc... Index must be constants!
For variable index is much easier to use temporally variable to hold result, than to work with pointers, etc in ASM. It can be done, I think that I post somewhere i TFT topic code for that.
Example for variable index:

pbpTmp VAR BYTE/ WORD/LONG
pbpTmp = Array[i]
@MOVE?BP _pbpTmp , TMP_32BIT

pedja089
- 24th March 2016, 09:13
Here is generated array definition and macros from LST file

; C:\USERS\ADMIN\DESKTOP\NEW FOLDER (5)\UNTITLED.PBP 00011 A00022 ArrayB var byte[10]
_ArrayB EQU RAM_START + 022h
; C:\USERS\ADMIN\DESKTOP\NEW FOLDER (5)\UNTITLED.PBP 00012 A0002C ArrayW var word[10]
_ArrayW EQU RAM_START + 02Ch
; C:\USERS\ADMIN\DESKTOP\NEW FOLDER (5)\UNTITLED.PBP 00013 A00040 ArrayL var long[10]
_ArrayL EQU RAM_START + 040h

; C:\USERS\ADMIN\DESKTOP\NEW FOLDER (5)\UNTITLED.PBP 00015 Arrayb[1]=ArrayB[2]
MOVE?BB _ArrayB + 00002h, _ArrayB + 00001h

; C:\USERS\ADMIN\DESKTOP\NEW FOLDER (5)\UNTITLED.PBP 00016 Arrayw[1]=ArrayW[2]
MOVE?WW _ArrayW + 00004h, _ArrayW + 00002h

; C:\USERS\ADMIN\DESKTOP\NEW FOLDER (5)\UNTITLED.PBP 00017 ArrayL[1]=ArrayL[2]
MOVE?NN _ArrayL + 00008h, _ArrayL + 00004h
For this test code

ArrayB var byte[10]
ArrayW var word[10]
ArrayL var long[10]

Arrayb[1]=ArrayB[2]
Arrayw[1]=ArrayW[2]
ArrayL[1]=ArrayL[2]
I hope that my explanation are understandable, my English is not good as my PBP :) .
Please, feel free to correct me.

longpole001
- 24th March 2016, 12:38
ok ill give that a go , the array that have been defined were existing sdc_buffer of 255bytes that i use for data transfer to spi chips so all this is about building the buffers ready to write the records for this section


i have the time in sec / laps count = lap time avg (result + remander) in sec
this then needs to be placed in to the record as days/hour/mins/sec/100th
here is the fisrt attempt in nbit math for this



'------- NbIT Math 32bit length get lap average time value -------------
glc_s = SDC_buffer[24] ' get the current lap count into tmp var ( Nmath wont allow indexed var)

@ MOVE?BP _glc_s,_Tmp32bit_1 ' copy lap value into tmp1
@ MATH_DIV _Tmp32bit_3,_Tmp32bit_1,_Result_32bit ' Tmp32bit_3 hold last lap time div total laps = lap time in secs , REg_Z holds remainder sec
@ MOVE?PB REG_Z, _glc_s ' copy sec remainder to tmp pbp var ( non indexed)
SDC_buffer[44] = glc_s ' copy remainder to AVG lap time 1/100th buffer

@ MOVE?CP 60,_Tmp32bit_1 ' copy 60 value into tmp1 for minutes div
@ MATH_DIV _Result_32bit,_Tmp32bit_1,_Tmp32bit_3 ' Result_32bit ( laps in sec div 60 = minutes Reg_Z holds remainder sec
@ MOVE?PB REG_Z, _glc_s ' copy min remainder to tmp pbp var ( non indexed)
SDC_buffer[45] = glc_s ' copy min remainder to AVG lap time secs buffer

@ MATH_DIV _Tmp32bit_3,_Tmp32bit_1,_Result_32bit ' _Tmp32bit_3 (laps in mins div 60 = hours ,Reg_Z holds remainder mins
@ MOVE?PB REG_Z, _glc_s ' copy hour remainder to tmp pbp var ( non indexed)
SDC_buffer[46] = glc_s ' copy hour remainder to AVG lap time mins buffer

@ MOVE?CP 24,_Tmp32bit_1 ' copy 24 value into tmp1 for days div
@ MATH_DIV _Result_32bit,_Tmp32bit_1,_Tmp32bit_3 ' Result_32bit ( laps in hours div 24 = days Reg_Z holds remainder hours
@ MOVE?PB REG_Z, _glc_s ' copy days remainder to tmp pbp var ( non indexed)
SDC_buffer[47] = glc_s ' copy days remainder to AVG lap time hours buffer

@ MOVE?PW _Tmp32bit_3,_glc_s ' copy days result to tmp pbp var ( byte size max value = 7)
glc_s = glc_s << 5 ' move day value to bit7-5 from bit2-0
SDC_buffer[47] = glc_s + SDC_buffer[47] ' assemble days + hours to AVG lap time day/hours buffer

pedja089
- 24th March 2016, 12:53
I'm not sure, but something might be wrong here...
Looking at this 2 lines
glc_s = SDC_buffer[24] ' get the current lap count into tmp var ( Nmath wont allow indexed var)
@ MOVE?BP _glc_s,_Tmp32bit_1 ' copy lap value into tmp1
And you sad that you have array of bytes.
So glc_s is byte, and max time that can hold is 255 sec.
And then I lost it...
Why you bother with N bit math if your max result is only byte wide? There is more than 255sec in day, so day will be 0 always, even hour...
You are doing something fundamentally wrong here.

longpole001
- 25th March 2016, 00:28
ok there is alot more to this that what your seeing here for sure

the buffers index is used in alot other sections of the code ,
in this case the buffers as are used as tmp storege and also in some of final assembaly for the section to be writen , the data being assembled is not just from this section but from alot of other parts as well

this section is to contain fast/slow/avg lap time information , speed calculations for fast/slow laps , sublap ( time between mulit points that make up a lap) , fast/slow sublap times , as well as other data

this section uses data that has been recorder previously and then this section accumulats the " stats " for that record, that information is then written on the header page for that record , further information is writen after that as well if other options are used , before the next event is started


i am still in the write code and see phase for this section