N bit x M bit divide routine
Thread Starter
Member
iTrader: (2)
Joined: Mar 2006
Posts: 236
Likes: 0
From: Hudson, OH
Car: '87 Formula
Engine: Ramjet 350
Transmission: T56
Axle/Gears: 3.23
N bit x M bit divide routine
...Anyone willing to share, if they have one, or point me a direction? I'm also yahoo'ing for binary divide routines, but I'd like to understand before trying to implement.
16 x 16 isn't going to cut it for what I'm trying to do.
Need to do 64 bit divide by 32 bit.
Thanks,
Ben
16 x 16 isn't going to cut it for what I'm trying to do.
Need to do 64 bit divide by 32 bit.
Thanks,
Ben
Supreme Member
iTrader: (2)
Joined: Jan 2002
Posts: 9,962
Likes: 5
From: Moorestown, NJ
Car: 88 Camaro SC
Engine: SFI'd 350
Transmission: TKO 500
Axle/Gears: 9-bolt w/ 3.23's
Re: N bit x M bit divide routine
Division routines of that nature are SLOW due to their iterative nature. See the 7747/8063/8746 hacs. Those ECMs lacked the FDIV/IDIV commands so they had routines that did it the long way.
Paired together, the IDIV/FDIV routines can do a max of 32 bit/32 bit if you apply scalars to the values you wish to use in the calculation. Basically you divide the numbers to get the integer portion, and then use FDIV to resolve the remainder. I use those so I can have 32 bit precision in my mass airflow based fuel calcs.
Paired together, the IDIV/FDIV routines can do a max of 32 bit/32 bit if you apply scalars to the values you wish to use in the calculation. Basically you divide the numbers to get the integer portion, and then use FDIV to resolve the remainder. I use those so I can have 32 bit precision in my mass airflow based fuel calcs.
Supreme Member
iTrader: (2)
Joined: Jan 2002
Posts: 9,962
Likes: 5
From: Moorestown, NJ
Car: 88 Camaro SC
Engine: SFI'd 350
Transmission: TKO 500
Axle/Gears: 9-bolt w/ 3.23's
Re: N bit x M bit divide routine
Heres an example of the 32 / 32. You can also use the IDIV/FDIV command to do a long division routine to handle higher values such as your 64 / 32 in the same way that you would with decimal, but this really starts sucking processor time. Each division command is 40 cycles, plus whatever time youd add working off of the stack/saving portions of the final result.
Code:
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Calculate base pulsewidth
;~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
LFUEL00 LDX #$0000 ;Clear X
PSHX ;
PSHX ;
PSHX ;Allocate some space on the stack
TSY ;Get stack pointer into Y
;
;-Gms/sec airflow x DRP
;
LDD L020B ;Load DRP period
LDX L01D7 ;Load filtered gms/sec x 128
JSR LF201 ;(gms/sec x DRP)/256
;
;-Gms/cyl air / AFR
;
XGDX ;Swap gms air/cyl x 32768 into X
CLRA ;
LDAB L026D ;Load AFR x 10
XGDX ;Swap AFR into X and gms/cyl air into D
IDIV ;(gms/cyl x 32768)/(AFR x 10)
STX 0,Y ;Save quotient
XGDX ;Swap remainder into X
CLRA ;
LDAB L026D ;Load in AFR
XGDX ;Swap AFR into X and remainder into D
FDIV ;Resolve remainder
STX 2,Y ;Save lower two bytes of result, overall result
;now = (required gms/cyl fuel x 3276.8) x 65536
;
;-[Gms/cyl fuel] / injector flowrate
;
LDD 0,Y ;Load two upper bytes of fuel/cyl
LDX L0257 ;Load inj flowrate x 3276.8
FDIV ;Upper two bytes of gms fuel/inj. flowrate
STX 4,Y ;Save result
LDD 2,Y ;Load in lower two bytes
LDX L0257 ;Inj flowrate x 3276.8
IDIV ;Lower two bytes / inj. flowrate
XGDX ;Get result into D
ADDD 4,Y ;Add in previous result
BCC LFUEL01 ;Bra if no overflow
;
LDD #$FFFF ;Clear overflow
;
LFUEL01 PULX ;Clean up the stack
PULX ;
PULX ;
STD L0271 ;Save it, BPW Last edited by dimented24x7; Aug 10, 2007 at 09:50 PM.
Thread Starter
Member
iTrader: (2)
Joined: Mar 2006
Posts: 236
Likes: 0
From: Hudson, OH
Car: '87 Formula
Engine: Ramjet 350
Transmission: T56
Axle/Gears: 3.23
Re: N bit x M bit divide routine
Thanks, I knew about the idiv then fdiv to find remainder. What I was actually working on also was try to find the 'sweet spot' in what I needed calculated. For example, I'm calculating miles/gallon, I have a 64 bit fuel counter (don't think I need this high for fuel but for now I do), and 32 bit distance counter. I figure I can use bits 10 through 26 for distance, giving me a resolution of (IIRC, don't have the TI-89 in front of me), something like .256 miles. Same for the fuel. And I could just shift the bits to get the 16 bits I need. Still doesn't go quite as high as I would like. I think bits 10 - 26 acutally gives resolution of .5 miles, and maxes at 16k or something like that. Might have to just deal with it though, might be more trouble than its worth. Fuel, going in .007 gallons resolution gives max of 200 some gallons, again dont remember but you get the idea I hope. This way I can still use idiv/fdiv with no fancy stuff.
Anyhow thats my idea, though I was hoping for the full 64/32 to be exactly precise with full range.
With the long division, might look at that too and see if I can come up with a good algorithm, I'm still learning this stuff, I don't have a lot of experience in assembly.
Thanks
Anyhow thats my idea, though I was hoping for the full 64/32 to be exactly precise with full range.
With the long division, might look at that too and see if I can come up with a good algorithm, I'm still learning this stuff, I don't have a lot of experience in assembly.
Thanks
Last edited by 5.7RamJet; Aug 10, 2007 at 11:58 PM.
Supreme Member
iTrader: (1)
Joined: Jan 2002
Posts: 4,432
Likes: 1
From: garage
Engine: 3xx ci tubo
Transmission: 4L60E & 4L80E
Re: N bit x M bit divide routine
Determine what you need for accuracy with the inputs you have. The PW and time isn't that accurate with a stock 1990's GM cal. The inputs and sensors determine what you need for accuracy.
Supreme Member
iTrader: (2)
Joined: Jan 2002
Posts: 9,962
Likes: 5
From: Moorestown, NJ
Car: 88 Camaro SC
Engine: SFI'd 350
Transmission: TKO 500
Axle/Gears: 9-bolt w/ 3.23's
Re: N bit x M bit divide routine
What I would probably do is accumulate the total grams of fuel consumed over a trip in a 32 bit counter as grams x 256 and use that accumulated value along with the distance traveled to do the calculations. This would only require 32 bit precision, which is relatively easy to do. The other option is to calculate it based on the derivative of the fuel consumption and speed and get an instantanious gallons/mile fuel consumption. You can then average this into an overall value that approximates the gallons per mile of fuel consumption for some duration of the trip.
The precision of your calculations is limited by the precision of the hardware. Even my MAF routine above is overkill given the precision of the injector drivers. Your gallons per mile fuel consumption is only three significant digits, so there isnt a real need for ultra-precise measurement. This is, as the old saying goes, measure with a micrometer, mark with chalk, cut with an ax.
The precision of your calculations is limited by the precision of the hardware. Even my MAF routine above is overkill given the precision of the injector drivers. Your gallons per mile fuel consumption is only three significant digits, so there isnt a real need for ultra-precise measurement. This is, as the old saying goes, measure with a micrometer, mark with chalk, cut with an ax.
Trending Topics
Thread Starter
Member
iTrader: (2)
Joined: Mar 2006
Posts: 236
Likes: 0
From: Hudson, OH
Car: '87 Formula
Engine: Ramjet 350
Transmission: T56
Axle/Gears: 3.23
Re: N bit x M bit divide routine
Forgive me for my ignorance...
What you suggest, if I understand, is only accumulate for each trip, which probably is going to be pretty small amount, representable by 32 bit number. Same with the distance, 32 bits.
So then using the upper 2 bytes, if we're talking grams of fuel, is that value times 256, would be the actual value. So we are forgetting about the lower two bytes, since they will prove to be insignificant after you do the calculation. So, doing 16 bit divide by 16 bit for fuel and distance, gives you your answer. I hope I understand that right.
Now, my problem with that is that you are limited by the 32 bit number in what you can accumulate. I wanted to have a running total, long term not trips then reset.
If I seem like I'm going in circles here, I'm sorry. Maybe I'm not understanding what you're suggesting to do.
I understand the precision, and not needing say the lower two bytes of PW accumlation, but I did want to be able to calculate to within 0.01 gallon or so...and distance to within .25 or .5 miles.
For example, distance, if I use 32 bits, and only use upper two bytes for calc's, then (2^16)/2000 = +/- 32.77 miles for accuracy. The good thing is that I can go up to 2 million miles. If I use the middle two bytes, accuracy is +/- 0.128 miles, but I can only calculate up to 8388 miles before rollover. Hence the reason I was thinking of shifting the bits, then I could have accuracy withing +/- .25 miles and calc up to 16k miles.
Same applies to Fuel.
The idea of using large accumulated fuel and distance, is I'm not going to get an update on MPG until I've traveled a larger distance and used more fuel. Like above, I'd have to travel 32 miles before I got a calculation that wasn't 0mpg, using upper 32 bits.
Again sorry if I'm missing your point.
What you suggest, if I understand, is only accumulate for each trip, which probably is going to be pretty small amount, representable by 32 bit number. Same with the distance, 32 bits.
So then using the upper 2 bytes, if we're talking grams of fuel, is that value times 256, would be the actual value. So we are forgetting about the lower two bytes, since they will prove to be insignificant after you do the calculation. So, doing 16 bit divide by 16 bit for fuel and distance, gives you your answer. I hope I understand that right.
Now, my problem with that is that you are limited by the 32 bit number in what you can accumulate. I wanted to have a running total, long term not trips then reset.
If I seem like I'm going in circles here, I'm sorry. Maybe I'm not understanding what you're suggesting to do.
I understand the precision, and not needing say the lower two bytes of PW accumlation, but I did want to be able to calculate to within 0.01 gallon or so...and distance to within .25 or .5 miles.
For example, distance, if I use 32 bits, and only use upper two bytes for calc's, then (2^16)/2000 = +/- 32.77 miles for accuracy. The good thing is that I can go up to 2 million miles. If I use the middle two bytes, accuracy is +/- 0.128 miles, but I can only calculate up to 8388 miles before rollover. Hence the reason I was thinking of shifting the bits, then I could have accuracy withing +/- .25 miles and calc up to 16k miles.
Same applies to Fuel.
The idea of using large accumulated fuel and distance, is I'm not going to get an update on MPG until I've traveled a larger distance and used more fuel. Like above, I'd have to travel 32 miles before I got a calculation that wasn't 0mpg, using upper 32 bits.
Again sorry if I'm missing your point.
Supreme Member
iTrader: (2)
Joined: Jan 2002
Posts: 9,962
Likes: 5
From: Moorestown, NJ
Car: 88 Camaro SC
Engine: SFI'd 350
Transmission: TKO 500
Axle/Gears: 9-bolt w/ 3.23's
Re: N bit x M bit divide routine
One issue with accumulating everything over several runs is that your going to have to tweak the RAM table a little to allow you to free up some space that can be used as non-volatile RAM. In the ECMs, only a portion of the memory is left intact after each shut down, and its usually pretty full, so youd need to edit what addresses are cleared and such. If I where to save somehting, it would probably only be an 8-bit value representing the overall fuel economy. Id also probably just use statistics to get an average running value or maybe even just the lag filter routine, rather then trying to save 12 or 16 bytes. That way you have a little more flexibility as to where you can put things in the memory map.
Also, you dont need to have super precise values. 32 bit, or even 16 bit precision will be more then enough. You just need to scale the values to have good resolution (for example, store the distance as something like feet, rather then miles) and set the order of operations up in such a way that you optimize your precision. A good rule of thumb is to scale/set up the values so that theyre large at the start of the calculations and they get progressivly smaller in magnitude as the calculations continue on to the final value. This preserves precision. Setting the routines up can take some thought, but its better in the long run then using brute force. You should try to make routines as short as possible so that you dont eat up processing time that could be used for other things.
Also, you dont need to have super precise values. 32 bit, or even 16 bit precision will be more then enough. You just need to scale the values to have good resolution (for example, store the distance as something like feet, rather then miles) and set the order of operations up in such a way that you optimize your precision. A good rule of thumb is to scale/set up the values so that theyre large at the start of the calculations and they get progressivly smaller in magnitude as the calculations continue on to the final value. This preserves precision. Setting the routines up can take some thought, but its better in the long run then using brute force. You should try to make routines as short as possible so that you dont eat up processing time that could be used for other things.
Thread Starter
Member
iTrader: (2)
Joined: Mar 2006
Posts: 236
Likes: 0
From: Hudson, OH
Car: '87 Formula
Engine: Ramjet 350
Transmission: T56
Axle/Gears: 3.23
Re: N bit x M bit divide routine
One issue with accumulating everything over several runs is that your going to have to tweak the RAM table a little to allow you to free up some space that can be used as non-volatile RAM. In the ECMs, only a portion of the memory is left intact after each shut down, and its usually pretty full, so youd need to edit what addresses are cleared and such.
1. Shortened stack from 01C2 to 01D8.
2. Moved variables (excluding maskable mode words) to new segment of shortened stack. Found this out the hard way after swapping the words then having issues with immediate addressing, since they were past $00FF.
3. Changed all addressing to reflect changed addresses.
4. Changed initializatoin routines to exclude clearing the now free NV RAM locations.
5. Now have $00EA - $00FF of free NV RAM. Don't seem to have any troubles with it so far.
6. Also, now have a routine that is called to clear the NV RAM spaces where the counters are stored, called from ALDL MODE 10.
7. I'm using MonteCarSlow's code, if you don't remember I can look up the link, and he was having problems with it, but it seems to work fine for me (he was using NVSRAM module). Code is running in LSEG_2, oil temp. This is a 6.25msec routine I think? Haven't gone through my code to see how many possible cycles, but I'd think it should be fine.
In light of all that, and the fact that it's all in place and working correctly, and the fact that I don't plan to need any more RAM (at least for now
), would you still do it differently?(Now you understand why I'm trying to make what I have work like crazy
Trust me, I'm being open-minded, if I seem stubborn) Thread
Thread Starter
Forum
Replies
Last Post




