PDA

View Full Version : Retrieving 32bit Multiply Result



Darrel Taylor
- 6th July 2003, 23:59
Here's an example that I find rather useful from time to time.
You may have seen in the manual that when you multiply two 16bit numbers together, the result is a 32bit number that can then be used with the DIV32 command. But the 32bit multiply result is not available to the user, it's only in PBP system variables where you can't get at it.

This little routine let's you retrieve that 32 bit result.


A32bitVar var word[2]
Dummy var word

ASM
GetMulResult macro Dword
MOVE?WW R2, Dword ; Low Word
MOVE?WW R0, Dword + 2 ; High Word
endm
ENDASM

Dummy = 1000
Dummy = Dummy * Dummy
@ GetMulResult _A32bitVar

end

The 32 bit result for 1,000,000 is now contained in the two words of A32bitVar.

HTH,
Darrel Taylor

Darrel Taylor
- 7th July 2003, 01:16
And here's the other side of the coin.

Suppose you want to put a 32 bit number in the PBP system vars where it can be used by DIV32.
But you don't want to have to multiply two numbers together to get it.

This allows you to enter a constant, up to 2,147,483,648 which can then be used by DIV32.



W1 var word

ASM
PutMulResult macro Const32
MOVE?CB low Const32, R2
MOVE?CB low (Const32 >> 8), R2 + 1
MOVE?CB low (Const32 >> 16), R0
MOVE?CB low (Const32 >> 24), R0 + 1
endm
ENDASM

@ PutMulResult 1000000 ; Load PBP internal vars - Max= 2,147,483,648
W1 = DIV32 300 ; Divide 1000000/300

' W1 will now contain 3333

@ PutMulResult 10562010
W1 = DiV32 1000 ; Divide 10562010/1000

' W1 is now 10562


-OR-

If the number is contained in a 2 word variable. You can load the "MUL result" like this...
Asm
PutMulResult?D macro Din
MOVE?BB Din, R2
MOVE?BB Din + 1 , R2 + 1
MOVE?BB Din + 2, R0
MOVE?BB Din + 3, R0 + 1
RST?RP
endm
EndAsm

DWord VAR WORD[2] ; holds a 31-bit value

@ PutMulResult?D _DWord ; Load PBP internal vars - Max= 2,147,483,648
W1 = DIV32 10000 ; 31-bit value / 10,000


The possibilties, are endless

HTH,
Darrel Taylor

kasapo
- 27th February 2005, 14:05
Hi darel,

i have a motor control application. in my application pic 16f877 is reading 2 position and then take the ratio of these values and multiply with the constant velocity. for example
x=5 y=10 then Vy = Vc (constan velocity) , Vx = Vc*x/y
so two motor begin and stop at the same time. i wrote some code by using Div32 but sometimes i cannot get the values thet it must be.

// for Trial i give posy greater than posx
POSX VAR WORD
POSX1 VAR POSX.BYTE1
POSX0 VAR POSX.BYTE0

POSY VAR WORD
POSY1 VAR POSY.BYTE1
POSY0 VAR POSY.BYTE0

V VAR WORD
V0 VAR V.BYTE0
V1 VAR V.BYTE1

HV VAR WORD
HV0 VAR HV.BYTE0
HV1 VAR HV.BYTE1

A VAR WORD
A0 VAR A.BYTE0
A1 VAR A.BYTE1


C VAR WORD
C1 VAR C.BYTE1
C0 VAR C.BYTE0

DUMMY VAR WORD


Asm
PutMulResult macro Const32
MOVE?CB Low Const32, R2
MOVE?CB Low (Const32 >> 8), R2 + 1
MOVE?CB Low (Const32 >> 16), R0
MOVE?CB Low (Const32 >> 24), R0 + 1
endm
EndAsm

GoSub USBREAD
POSX1=HB
POSX0=LB
GoSub USBREAD
POSY1=HB
POSY0=LB

IF POSY > 6554 Then
DUMMY = POSY * 10 // i scale posy by 10
C= Div32 POSX
@ PutMulResult 2236920 // i also enter here the scaled c constant velocity by 10
V= Div32 C
HV = 34 / C
Else
DUMMY = POSY * 10
C = DUMMY / POSX
@ PutMulResult 2236920
V= Div32 C // when this is greter than 16 bits it returns ffff
HV = 34 / C
EndIF

how can i get the V when it is greater than 16 bit ?
thanks

Darrel Taylor
- 28th February 2005, 03:47
There's no way to do that with DIV32. The Quotient must be less than 65535.

You would need a TRUE 32 bit divide routine.

Or you could use the Floating Point Math routines from melabs.
http://www.melabs.com/resources/fp.htm

Darrel

kasapo
- 2nd March 2005, 09:50
hi darrel ,
do you have some example about the usage of floating point numbers.

after i do my multiplication and division how can i use aint variable?
i have to send the aint to my motor controller byte by byte.

thanks

mytekcontrols
- 18th June 2005, 00:09
Hi Darrel,

I like your ideas about getting at DIV32 system variables, but I have a slightly different situation. How do I use a variable for the divisor that wont violate the 15 bit rule?

I tried the following example, but it don't work (I get: Error Bad expression):


divisor var word
dummy var word

dummy = DIV32 divisor


I really need the ability to alter the divisor via program control, and at times it will need to be bigger then an 8-Bit value. Any ideas?

Thanks,

Edit: Opps! my mistake. It does work properly with a word variable as the divisor, just so long as you stay with the 15 bit rule (32767). This is good news.

Darrel Taylor
- 18th June 2005, 00:38
hehe, :)

DT

Josuetas
- 26th July 2007, 20:49
I just saw this link. it is of great interest to me right now...

I have this question... how do you add two of these Dwords?

how do i know if the add of two words overflows?
i.e. $1FFFE + $2E

my guess is to add the lower words $FFFE+$2E. But how do i know if there is an overflow? so that i can add one to the higher WORD? even worse..

i.e. $EFFF8 + $6FFE4

My guess again: add two lower words... if over flow add two higher words +1, else add two higher words....

I think i can manage myself once i am sure abour the overflow

Thanks,

Darrel Taylor
- 27th July 2007, 08:08
For words and bytes, you can detect an overflow by testing if the result is less than what you added.

Due to trucation of a 16-bit word ...
$FF00 + $0180 = $0080

So the result will always be less than either of the values added if an overflow occurs.


I think i can manage myself once i am sure abour the overflow

I'm sure you could. But that's just not my way ... :eek:


;Initialize your hardware first

A VAR WORD[2]
B VAR WORD[2]
Result VAR WORD[2]
OVRFLOW32 VAR BIT

ASM
; ===== Load 32bit Constant into DWORD =============================
MOVE?CD macro C32in, Dout ; Max= 4,294,967,296
MOVE?CB low C32in, Dout
MOVE?CB low (C32in >> 8), Dout + 1
MOVE?CB low (C32in >> 16), Dout + 2
MOVE?CB low (C32in >> 24), Dout + 3
endm
ENDASM

@ MOVE?CD 0xEFFF8, _A ; Load 983,032 into A
@ MOVE?CD 0x6FFE4, _B ; Load 458,724 into B

GOSUB Add32

LCDOUT $FE,1, "A= ",HEX4 A[1],":",HEX4 A[0]
LCDOUT $FE,$C0,"B= ",HEX4 B[1],":",HEX4 B[0]
LCDOUT $FE,$90,"Res= ",HEX4 Result[1],":",HEX4 Result[0]
LCDOUT $FE,$D0,"OVRFLOW32 = ", BIN1 OVRFLOW32
stop

; ===== Add 2 32bit variables ======================================
Add32:
OVRFLOW32 = 0
Result[0] = A[0] + B[0]
IF Result[0] < B[0] then Result[1] = 1
Result[1] = Result[1] + A[1]
IF Result[1] < A[1] then OVRFLOW32 = 1
Result[1] = Result[1] + B[1]
IF Result[1] < B[1] then OVRFLOW32 = 1
RETURN

Which displays ...
A= 000E:FFF8
B= 0006:FFE4
Res= 0015:FFDC
OVRFLOW32 = 0

HTH,

Josuetas
- 28th July 2007, 15:01
Checking for a smaller result is a simple trick, thanks,

right now my code is never suposed to exced the Max= 4,294,967,296
so i am ignoring the OVRFLOW32 = 0.

This is the code that i am using


Bigword var word [2]
BigwordL var BigWord(0)
BigwordH var BigWord(1)
Bigword1 var word [2]
Bigword1L var BigWord(0)
Bigword1H var BigWord(1)


AddTwoBigWords: 'Adds Bigword1 and BigWord2 result in BigWord
BigWordH = BigWordH + BigWord1H ;ignoring any overflow
BigWordL = BigWordL + BigWord1L
if BigWordL < BigWord1L then
BigWordH = BigWordH+1 ;ignoring any overflow
endif
return



Would this be ok? i made some tests and it seems ok but your experience might see anything wrong here.

Darrel Taylor
- 28th July 2007, 15:35
Yup,

Looks great to me.

Nice reduction.
<br>

Josuetas
- 31st July 2007, 18:46
I was so confused about the Multiply operation that i posted here but.... i am now just using ** and * :s sorry

Josuetas
- 1st August 2007, 18:33
Well i am really proud of this, i Hope its ok.

For anyone in need of a Division of a BigWord by some number i found this problem:

Lets think of a BigWord as considered before ^

Now you might want to Divide a value stored in tBigWord1 by some other value, in this case (EXAMPLE CODE) the value is stored in factoriva.

One could use the DIV32 function as proposed by Darrel in this or other post BUT if factoriva is too small the result CAN be higher than a word size FFFF, and the the result is no good.

For example:

4:01F5 DIV32 2 the result of DIV32 is

Result = FFFF, Remainder = 01F7 !! Wrong i guess

This code is possible just thanks to Darrel`s @ PutMulResult?D MACRO



Bigword var word [2]
BigwordL var BigWord(0)
BigwordH var BigWord(1)
Bigword1 var word [2]
Bigword1L var BigWord(0)
Bigword1H var BigWord(1)

MainLoop:
lcdout $fe,1
tbigword1H = 4 ' My Dollars Value High Word
tbigword1L = 501 ' My Dollars value Low Word
cents = 24 ' My cents value

GOSUB DIVBIGWORD
HSEROUT [#FactorIva," ",HEX4 tBigWordH,":", HEX4 tBigWordHL,10,13]

FactorIva= FactorIva+ 1
IF FactorIva= 101 THEN
END
ENDIF
GOTO MainLoop

'This SUB receives tBigWord1(Dword) a value to be divided by
'FactorIva (word), Result in tBigWord, works for any value of FactorIva
'and tBigWord1 in their limits.
DIVBigWord:
tBigWordH= tBigWord1H / FactorIva
tBigWord1H = tBigWord1H // FactorIva
@ PutMulResult?D _tBigWord1
tBigWordL = DIV32 FactorIva
Remainder = R2
RETURN


This code in the serial port os The value tBigWord1 Divided for Factors 1 to 100
Seems to work.
Factor Result
2 0002:00FA

Remember to Add the @ PutMulResult?D MACRO posted by Darrel at the begining of the Code.

Nicmus
- 24th January 2008, 17:30
Hello everyone,

I was wandering if it is possible to implement the extended 32 bit idea to something as simple as for / next loop.
How will this simple loop look like if I need to deal with more than word size index:

For index =0 to big_number
Hserout [record(index),13,10]
Pause 100
Next

Is it possible to have a big_number = 1,000,000 – 2,000,000?

Thank you for your input.

Nick

skimask
- 24th January 2008, 17:32
Is it possible to have a big_number = 1,000,000 – 2,000,000?
Nick

It's directly possible if you have the PBP 2.50a upgrade, which supports signed/32 bit LONG variables...

mister_e
- 24th January 2008, 20:46
for PIC18 only !

skimask
- 24th January 2008, 20:52
for PIC18 only !

Got my back everywhere, dontcha?

Nicmus
- 25th January 2008, 00:51
Thank you gents for your replies.
Unfortunately for me I’m dealing with a old application which employs a PIC16F876A and needs an upgrade to be able to handle a larger number of records.
The code space is not a problem so I guess I will have to figure a way to get around this problem.
Basically I receive a 8 bytes decimal number which is the total number of records. What I’m planning to do is create two loops.
First I will separate the incoming Big_number in Big_number_low (last four bytes (max 9999)) and Big_number_high (first four MS bytes (max 9999)).
The code in my last post should change to:

For index_1=0 to Big_number_low
HSEOUT [sentence(index_1)]
Next
For index_2=0 to Big_number_high
For index_3=0 to 9999
HSEROUT [sentence(index_3)]
Next
Next

I’m wandering if this will do or I need to look deeper into the problem.
Any comments will be appreciated.

Regards,

Nick

Darrel Taylor
- 25th January 2008, 01:06
Not sure how you're going to get a 1,000,000 element array with a PIC ...
Even with PBP 2.50


For index =0 to big_number
Hserout [record(index),13,10]
Pause 100
Next
Not enough RAM.
<br>

Nicmus
- 25th January 2008, 01:21
Thank you gents for your replies.
I’m sorry for not making it clear. I’m receiving each sentence one at the time and send them out. My problem is that I know how many I will receive (Big_number) and I need to keep track on how many I send out to match the Big_number. So it gets down to only handling a 6digi number.
Unfortunately for me I’m dealing with a old application which employs a PIC16F876A and needs an upgrade to be able to handle a larger number of records.
The code space is not a problem so I guess I will have to figure a way to get around this problem.
Basically I receive a 8 bytes decimal number which is the total number of records. What I’m planning to do is create two loops.
First I will separate the incoming Big_number in Big_number_low (last four bytes (max 9999)) and Big_number_high (first four MS bytes (max 9999)).
The code in my last post should change to:

For index_1=0 to Big_number_low
HSEOUT [sentence(index_1)]
Next
For index_2=0 to Big_number_high
For index_3=0 to 9999
HSEROUT [sentence(index_3)]
Next
Next

I’m wandering if this will do or I need to look deeper into the problem.
Any comments will be appreciated.

Regards,


Nick

Darrel Taylor
- 25th January 2008, 01:28
How are you going to get a 1,000,000 element array with a PIC?



For index_1=0 to Big_number_low
HSEROUT [sentence(index_1)]
Next

Not enough RAM.
<br>

Nicmus
- 25th January 2008, 01:57
Hi Darrel,
I’m sorry for not presenting the complete picture.
I’m reading a .txt file from a USB media. The first line of this file gives me the total number of records in the file.
I’m reading the records one by one in a big loop:

Read Big_number
For index = 0 to Big_number
Read record
HSEROUT [record}
If index => Big_number then quit
Next

It all works fine if Big_number is limited to word size.
Now the requirement changed for larger number of records so I thought that your trick might apply here.
At the time I did that because I did not know, and I still don’t, to detect EOF.
Trying to read the device over the EOF will freeze the system.

Thank you for your interest.

Nick

Darrel Taylor
- 25th January 2008, 06:27
That makes things a bit easier ...
big_number VAR WORD[2] ; 32-bit variable


ASM
;---[load a 32-bit constant into a 32-bit variable]-----------------
MOVE?CN macro Cin, Nout
MOVE?CW Cin & 0xFFFF, Nout ; Low Word
MOVE?CW (Cin >> 16), Nout + 2 ; High Word
endm
ENDASM


;-------------------------------------------------------------------
@ MOVE?CN 1000000, big_number

WHILE (big_number[1] > 0) OR (big_number[0] > 0)
Read record
HSEROUT [record]

big_number[0] = big_number[0] - 1
IF big_number[0] = $ffff THEN big_number[1] = big_number[1] - 1
WEND

Nicmus
- 25th January 2008, 13:28
Thank you Darrel,
I knew it can be done. I just did not know how, and your example turns few lights on in my brain.
I will give it a shot after work, today, and post the results.
Thanks again,

Nick

Nicmus
- 25th January 2008, 17:52
Hi Darrel,

I have a PBP copy installed on my work computer so I tried your code in a simple program to send out numbers (if I understood you correctly) from Big_number to 0.

I am using:
MCS 2.3.0.0
PBP 2.47
MPASM 5.03

This is the small program I’m trying to compile but I get a warning and an error:

INCLUDE "modedefs.bas"
DEFINE OSC 16
DEFINE LOADER_USED 1
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 4800
DEFINE HSER_CLROERR 1

big_number VAR WORD[2] ; 32-bit variable

ADCON1=6
CMCON=7

main:

@ MOVE?CN 1000000, big_number
WHILE (big_number[1] > 0) OR (big_number[0] > 0)
HSEROUT [#big_number[1],#big_number[0]]
big_number[0] = big_number[0] - 1
IF big_number[0] = $ffff THEN big_number[1] = big_number[1] - 1
WEND
pause 5000
goto main
ASM
;---[load a 32-bit constant into a 32-bit variable]-----------------
MOVE?CN macro Cin, Nout
MOVE?CW Cin & 0xFFFF, Nout ; Low Word
MOVE?CW (Cin >> 16), Nout + 2 ; High Word
endm
ENDASM
End


The messages I get are:

Warning[207] c:\big_num.asm 99: Found label after column 1.(MOVE?CN)
Error[108] c:\big_num.asm : Illegal character (1)

Any idea?

Regards,

Nick

skimask
- 25th January 2008, 18:03
Put the macro in the source code BEFORE the actual usage.

INCLUDE "modedefs.bas"
DEFINE OSC 16
DEFINE LOADER_USED 1
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 4800
DEFINE HSER_CLROERR 1
big_number VAR WORD[2] ; 32-bit variable
ADCON1=6
CMCON=7
goto main
ASM
;---[load a 32-bit constant into a 32-bit variable]-----------------
MOVE?CN macro Cin, Nout
MOVE?CW Cin & 0xFFFF, Nout ; Low Word
MOVE?CW (Cin >> 16), Nout + 2 ; High Word
endm
ENDASM
main:
@ MOVE?CN 1000000, big_number
WHILE (big_number[1] > 0) OR (big_number[0] > 0)
HSEROUT [#big_number[1],#big_number[0]]
big_number[0] = big_number[0] - 1
IF big_number[0] = $ffff THEN big_number[1] = big_number[1] - 1
WEND
pause 5000
goto main
End
[/code]

Nicmus
- 25th January 2008, 19:35
Hi Skimask,

I tried that first but I got 12 errors:

Error[113] c:\pbp\pbppicbasic14.lib428 : Symbol not previously defined (big_number).
Should I do any changes in pbppicbasic14.lib?
Thanks,

Nick

mister_e
- 25th January 2008, 19:54
edit this line

@ MOVE?CN 1000000, big_number
to

@ MOVE?CN 1000000, _big_number

Darrel Taylor
- 25th January 2008, 19:57
OOps!

Thanks Steve.

Nicmus
- 25th January 2008, 22:04
Thank you Darrel, Steve and Skimask,

No more errors.
One more clarification on the line:
@ MOVE?CN 1000000, _big_number
Does it make my big_number=1000000 in decimal?
If that is true should I see the counter going down from 1000000 to 0?
Am I processing the big_number right in my HSEROUT statement because when I run the program it starts counting down from 1516960.
How do I insert a new big_number

I will be away from the computer for the next 2 hours.
Thanks in advance for all the help.

Nick

Darrel Taylor
- 25th January 2008, 23:02
Yes, it loads 1 million into big_number.
But it's a 32-bit binary number, so you can't just display the high/low WORDs with DEC.

The hex representation of 1 million is F:4240.
Then change each word to Decimal F=15, 4240=16960
So it looks like it starts counting from 1516960

To convert the big_number to a readable decimal output takes a little more work.



HighDigits VAR WORD
LowDigits VAR WORD

;---[add this with the other macro's]---------------
ASM
PutMulResult?N macro Nin
MOVE?WW Nin, R2
MOVE?WW Nin + 2, R0
endm
ENDASM


;---[add this to your main loop]--------------------
@ PutMulResult?N _big_number
GOSUB SendBigNum
;---------------------------------------------------

SendBigNum:
HighDigits = DIV32 10000
LowDigits = R2
IF (HighDigits > 0) THEN
HSEROUT [DEC HighDigits, DEC4 LowDigits]
ELSE
HSEROUT [DEC LowDigits]
ENDIF
RETURN


How do I insert a new big_number
That depends on where the new big_number is coming from.

You said you're reading the file length from the USB device.
What format is it in, what variables are you storing it in.

Nicmus
- 26th January 2008, 00:47
Thank you Darrel,

I will add the new code to my program and report the results.

On the refreshing the big_number question:
I’m using a Viniculun device to read an USB storage media that lets me read one byte at the time, n bytes or the entire file in one shot.
The very first line in my data .txt file is the total number of records, 0 - 2,000,000, in fixed length (10 digit left padded with zeros.I used 10 digits to allow for up to 31 bit numbers if need be in the future), decimal format. The rest of the file are the records in fixed length (78 bytes) starting with "#" character, right padded with "~" character and ending with CR/LF. The data is only numerical and I do not process it, I just pass it to the Hserout. Every few records I must pause about 1 second to let the receiver process the information.

I can read the 10 digit number byte by byte, strip the leading zeros and transfer into my big_number variable. How am I going to do it? This is the $10,000,000 question.

I will fix my code right the way and work on the other problem.

I must commend you guys for taking my “what if?” question and make sure I get the best solution. I learned a lot with your help.

Regards,

Nick

Nicmus
- 26th January 2008, 04:24
I added the changes Darrel suggested and it all works fine.
I need to make small changes to the code to better fit my application and i will post it tomorrow.

Thanks again and good night!

Nick

Darrel Taylor
- 26th January 2008, 04:33
If you come back and have it counting from 0 to <strike>1,000,000</strike> File Length ...

I will ..., uh ...,

oh hell, I don't know what I'd do. :)
<br>

Nicmus
- 26th January 2008, 15:29
Hi Darrel,

Sorry for the delay. I had some hardware problems which I had to fix.
Also I’m using a USB to serial interface to communicate with HT and every now and then Windows will see my device as a mouse.
Here is what I have so far:
I am able to count down and send out the big_number. I made few changes to your code to format the output as a 8 digit number (kept the leading zeros).
I’m also receiving the big_number as two 4 digit decimal numbers.
The only thing left is to make one big_number from the two word size variable (in_high and in_low).
I was thinking to use your PutMultResult?D macro Din but I’m not quite sure how to do it.
Here is the latest working code:

INCLUDE "modedefs.bas"
@ device pic16F876a,hs_osc,pwrt_on, protect_on
DEFINE OSC 16
DEFINE LOADER_USED 1
DEFIne HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 4800
define HSER_CLROERR 1

HighDigits VAR WORD
LowDigits VAR WORD
big_number VAR WORD[2] ; 32-bit variable
in_low var word
in_high var word
led var PORTA.2

ADCON1=6
CMCON=7

ASM
MOVE?CN macro Cin, Nout
MOVE?CW Cin & 0xFFFF, Nout ; Low Word
MOVE?CW (Cin >> 16), Nout + 2 ; High Word
endm
ENDASM
ASM
PutMulResult?N macro Nin
MOVE?WW Nin, R2
MOVE?WW Nin + 2, R0
endm
ENDASM
pause 10000 ' Allow for the USB device to enumerate
hserout [13,10,"Waiting for Big_number",13,10] ' Add time out later
hserin [dec4 in_high,dec4 in_low]
main:
@ MOVE?CN 20000, _big_number
WHILE (big_number[1] > 0) OR (big_number[0] > 0)
big_number[0] = big_number[0] - 1
IF big_number[0] = $ffff THEN big_number[1] = big_number[1] - 1
@ PutMulResult?N _big_number
GOSUB SendBigNum
toggle led ' Show if any action
WEND
pause 5000
goto main
SendBigNum:
HighDigits = DIV32 10000
LowDigits = R2
'IF (HighDigits > 0) THEN
HSEROUT [DEC4 HighDigits, DEC4 LowDigits," and ",dec4 in_high,dec4 in_low,13,10]
'ELSE
'HSEROUT [DEC4 LowDigits,13,10]
'ENDIF
RETURN

End

Thanks again for your patience.

Nick

BTW: I'm practising to post code the right way.

Darrel Taylor
- 26th January 2008, 21:15
I’m also receiving the big_number as two 4 digit decimal numbers.
The only thing left is to make one big_number from the two word size variable (in_high and in_low).

This one I'm not so sure about. And I don't have anything handy to test it on.
I'm pretty sure it will work, but not Positive...

HighDigits = 100 ; Simulating File Length of 1,000,000
LowDigits = 0000

big_number[0] = HighDigits * 10000
big_number[1] = R0
big_number[0] = big_number[0] + LowDigits
IF (big_number[0] < LowDigits) THEN big_number[1] = big_number[1] + 1

P.S. To put code in a scrolling box that doesn't scrunch it all to the left, use ...

' --- code goes here ---

oops, nevermind. I see you're even using colors in the test area. :)
<br>

Nicmus
- 26th January 2008, 22:48
Hi Darrel,

I’m a bit confused by your last post.
I’m not sure were to add this code. Also I have the feeling that the big_number[0] and big_number[1] are switched from the way they are in my code.

Here is the code in “colors” format:


<font color="#000000"><b>INCLUDE </b><font color="#FF0000">&quot;modedefs.bas&quot;
</font><font color="#008000">@ device pic16F876a,hs_osc,pwrt_on, protect_on
</font><b>DEFINE </b>OSC 16
<b>DEFINE</b> LOADER_USED 1
<b>DEFINE </b>HSER_RCSTA 90h
<b>DEFINE </b>HSER_TXSTA 20h
<b>DEFINE </b>HSER_BAUD 4800
<b>DEFINE </b>HSER_CLROERR 1

HighDigits <b>VAR WORD
</b>LowDigits <b>VAR WORD
</b>big_number <b>VAR WORD</b>[2] <font color="#000080"><i>; 32-bit varia
</i></font>in_low <b>VAR WORD
</b>in_high <b>VAR WORD
</b>led <b>VAR </b>PORTA.2

ADCON1=6
CMCON=7

<b>ASM
</b><font color="#008000">MOVE?CN macro Cin, Nout
MOVE?CW Cin &amp; 0xFFFF, Nout </font><font color="#000080"><i>; Low Word
</i></font><font color="#008000">MOVE?CW (Cin &gt;&gt; 16), Nout + 2 </font><font color="#000080"><i>; High Word
</i></font><font color="#008000">endm
</font><b>ENDASM
ASM
</b><font color="#008000">PutMulResult?N macro Nin
MOVE?WW Nin, R2
MOVE?WW Nin + 2, R0
endm
</font><b>ENDASM
PAUSE </b>1000
<b>HSEROUT </b>[13,10,<font color="#FF0000">&quot;Waiting for Big_number&quot;</font>,13,10]
<b>HSERIN </b>[<b>DEC4 </b>in_high,<b>DEC4 </b>in_low]

main:
<font color="#008000">@ MOVE?CN 20000, _big_number
</font><b>WHILE </b>(big_number[1] &gt; 0) <b>OR </b>(big_number[0] &gt; 0)
big_number[0] = big_number[0] - 1
<b>IF </b>big_number[0] = $ffff <b>THEN </b>big_number[1] = big_number[1] - 1
<font color="#008000">@ PutMulResult?N _big_number
</font><b>GOSUB </b>SendBigNum
<b>TOGGLE </b>led
<b>WEND
PAUSE </b>5000
<b>GOTO </b>main
SendBigNum:
HighDigits = <b>DIV32 </b>10000
LowDigits = R2
<font color="#000080"><i>'IF (HighDigits &gt; 0) THEN
</i></font><b>HSEROUT </b>[<b>DEC4 </b>HighDigits, <b>DEC4 </b>LowDigits,<font color="#FF0000">&quot; and &quot;</font>,<b>DEC4 </b>in_high,<b>DEC4 </b>in_low,13,10]
<font color="#000080"><i>'ELSE
'HSEROUT [DEC4 LowDigits,13,10]
'ENDIF
</i></font><b>RETURN

END
</b>

How do I process the in_low and in_high variables to get the big_number before entering the main loop?
Am I pulling them right as DEC4 or should I do it differently?

Regards,

Nick

Darrel Taylor
- 26th January 2008, 23:11
Sorry. Should have used your variable names ...
big_number[0] = in_high * 10000
big_number[1] = R0
big_number[0] = big_number[0] + in_low
IF (big_number[0] < in_low) THEN big_number[1] = big_number[1] + 1Just stick it after the HSERIN.

P.S. Nice "Colors". :)

Nicmus
- 27th January 2008, 00:22
Hi Darrel,

I added your last lines and had to REM the line:



@ MOVE?CN 1000000, _big_number


After that everything works as intended.
I guess the macro this line was pointing to is no longer needed.
I will open an other thread with a question on detecting EOF.
There are no words to thank you enough for your help.

Best Regards,

Nick

Darrel Taylor
- 27th January 2008, 01:43
Yup, that statement/macro is no longer needed.

EOF marker for a .txt file is usually 26. That's a byte with the decimal value 26.
In hex it's 1A, ASCII it's ctrl-Z, whichever way you want to look at it.

Of course that ruins everything we just did. :(

And you're welcome. :)
<br>

Nicmus
- 27th January 2008, 02:08
Not really.
For now what we did will work just fine and buys me time.
But, and I’m sure you are the same way, if it can be improved, and you know it can, loosing few more hours of sleep doesn’t really matter. It will be a future project as I explained in my new post “Detecting EOF” (I will learn how to insert a link, I promise!)

It’s just like the CC commercial:
“The smile on your face after getting it done right…………Priceless “

Thousands of thanks again.

Nick

nomad
- 28th January 2008, 09:43
to add a link past link here .

for example, http://www.picbasic.co.uk/forum/misc.php?do=bbcode
adds this link http://www.picbasic.co.uk/forum/misc.php?do=bbcode ,
which is the link to the codes available and their usage.
(the "vB code" link near the bottom of the page)


there's also [THREAD] and [POST] codes, and other options to make it look all special. example:

click here for viagra!!

which takes you to your post I'm replying to, is done with:
click here for viagra!!

As you can see I'm really bored, but I'll stop wasting your time now. :)

Nicmus
- 28th January 2008, 15:15
Having fun and learning is my kind of treat.
Thanks Nomad for the crash course on posting links.

Nick