Truncated match.
PICList
Thread
'How to write code that no one will laugh at [OT]'
2000\03\09@102102
by
jamesnewton
Those tricks are at
http://www.piclist.com
under routines, math, basic math
Programming like that must be at least partly innate talent, 'cause I
haaaaavvve tried. <GRIN> I can do other things well, but the math stuff just
kills me. I'm still recovering from the blow to my ego from having my first
code challenge ignored.
One thing that I have learned is that
One must:
1. Care; to have the energy to:
2. Try; which will ALWAYS cause one to:
3. Fail; from which we will gain:
4. Experience; which will allow one to reliably:
5. Succeed
Thinking that one can skip step 3 is a common error. Success without
experience is luck and luck is not repeatable
Please mark further posts on this thread [OT].
---
James Newton (PICList Admin #3)
spam_OUTjamesnewtonTakeThisOuT
piclist.com 1-619-652-0593
PIC/PICList FAQ: http://www.piclist.com or .org
{Original Message removed}
2000\03\09@102510
by
Scott Dattalo
On Thu, 9 Mar 2000, James Newton wrote:
> I'm still recovering from the blow to my ego from having my first
> code challenge ignored.
At the risk of striking another blow, what challenge was that?
Scott
2000\03\09@110636
by
jamesnewton
|
Ok, I have a (probably little and fairly lame) code challenge! [ed: which
will probably be ignored 'cause its in Parallax mnemonics and its lame]
I needed a 16bit binary to decimal routine but I'm just about out of
registers. So I came up with a routine that pulls off one digit at a time
and gets rid of each digit by calling an io subroutine.
My best (so far) is 76 words and about 100 best to 500 worst case
instructions executed. Compare that to John Paysons marvel at 48
instructions, about 200 executed and 2 input, 5 output/temp registers. Mine
needs its input in 2 registers, returns the output in another and uses only
one temp register during the computation.
Hint: It's ugly. Think successive approximation.
Its posted already at
techref.massmind.org/microchip/math/radix/b2a-16b5alzs
but gents and ladies will not cheat and look at it until they have beat it
on their own. <GRIN>
Its in Parallax mnemonics, so use
www.geocities.com/SiliconValley/Network/9276/parallax.zip
or
http://www.picnpoke.com/parapic.zip
to convert to MicroChip mnemonics
---
James Newton .....jamesnewtonKILLspam
@spam@geocities.com 1-619-652-0593
http://techref.massmind.org NEW! FINALLY A REAL NAME!
Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
-----Original Message-----
From: pic microcontroller discussion list
[PICLIST
KILLspamMITVMA.MIT.EDU]On Behalf Of Scott Dattalo
Sent: Thursday, March 09, 2000 07:27
To: .....PICLISTKILLspam
.....MITVMA.MIT.EDU
Subject: Re: How to write code that no one will laugh at [OT]
Importance: Low
On Thu, 9 Mar 2000, James Newton wrote:
> I'm still recovering from the blow to my ego from having my first
> code challenge ignored.
At the risk of striking another blow, what challenge was that?
Scott
2000\03\09@173823
by
Rich Leggitt
> Ok, I have a (probably little and fairly lame) code challenge! [ed: which
> will probably be ignored 'cause its in Parallax mnemonics and its lame]
Do we get to destroy the original 16 bit number?
2000\03\09@181239
by
jamesnewton
Yes.
Input: 2 registers
Temp: 1 register
Output: 1 register
-------------------
total: 4 registers
Required at compile time: 1 subroutine to do something nice with the Output
value and it can then munch it. For example, you can shift the output
register out a port pin, leaving behind a zero.
The only thing that the main routine has to do is call the subroutine for
each digit of output with a valid number between 0 and 9 (or '0' and '9') in
the output register.
Possible improvements for extra credit (not in my code):
It would be nice if it had an option to output a "." after some number of
digits passed as a third input.
It would be nice to optionally skip leading digits that are zero.
Code that cannot be written for the PIC:
A general purpose routine that is given a pointer (FSR) to a register
holding the radix and followed by a count of the number of following bytes
that contain the binary number to be converted. Output each digit as it is
developed.
---
James Newton EraseMEjamesnewtonspam_OUT
TakeThisOuTgeocities.com 1-619-652-0593
http://techref.massmind.org NEW! FINALLY A REAL NAME!
Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
-----Original Message-----
From: pic microcontroller discussion list
[PICLIST
spam_OUTMITVMA.MIT.EDU]On Behalf Of Rich Leggitt
Sent: Thursday, March 09, 2000 14:39
To: @spam@PICLISTKILLspam
MITVMA.MIT.EDU
Subject: Re: How to write code that no one will laugh at [OT]
> Ok, I have a (probably little and fairly lame) code challenge! [ed: which
> will probably be ignored 'cause its in Parallax mnemonics and its lame]
Do we get to destroy the original 16 bit number?
2000\03\09@190144
by
Rich Leggitt
On Thu, 9 Mar 2000, James Newton wrote:
> Yes.
Hmmm... this is off the cuff, looks like about 40 instructions? Not
terribly esoteric I'm afraid, I'm sure there are much better ways -- Rich
; given 16 bit data in HI and LO, extract decimal digits
; requires one temp, HI and LO are destroyed.
clrf temp
skp
sub10k incf temp,f
movlw 10000 & 255
subwf LO,f
movlw 10000 >> 8
skpc
addlw 1 ; this sucks
subwf HI,f
bc sub10k
output(temp);
movlw 10
movwf temp
add1K decf temp,f
movlw 1000 & 255
addwf LO,f
movlw 1000 >> 8
skpnc
addlw 1
addwf HI,f
bnc add1k
output(temp);
clrf temp
skp
sub100 incf temp,f
movlw 100
subwf LO,f
bc sub100
movlw 1 ; this REALLY sucks
subwf HI,f
bc sub100
output(temp);
movlw 10
movwf temp
add10 decf temp,f
addwf LO,f
bnc add10
output(temp);
output(LO);
return
2000\03\10@025126
by
Nikolai Golovchenko
|
Hi James,
Is this what you want? This routine is slightly bigger :), but
saves one register and must be faster. I'm not sure how to
calculate the worst case.
test1
movlw 0xaf
movwf NumL
movlw 0x13
movwf NumH
clrf Digit
again
call BIN2DEC2
movfw Digit
andlw 0xF0
skpz
goto again
goto test1
; BIN2DEC2 STRIPS ONE DIGIT AT A TIME
; Author: Nikolai Golovchenko <techref.massmind.org/member/NG--944>
; Date: March 10, 2000
;
; Input:
; NumL
; NumH
; Output:
; Digit
;
; Notes 1)Input is changed after each call
; 2)Digit<4:7> contain state of conversion(don't change!)
; 3)Clear Digit<4:7> before first call
; 4)Digit<4:7> are clear for last digit
;
; ROM - 137 instructions
; RAM - 3 bytes
BIN2DEC2
movfw Digit
andlw 0xF0
movwf Digit
btfss Digit, 7
goto TenK1
btfss Digit, 6
goto Thou1
btfss Digit, 5
goto Hund1
btfss Digit, 4
goto Tens1
movfw NumL
movwf Digit
return
Tens1
bsf Digit, 4
btfss NumL, 6
goto Tens2
movlw 6
addwf Digit, f
movlw 0x3C ;Num -= 60;
subwf NumL, f
Tens2
btfss NumL, 5
goto Tens3
movlw 3
addwf Digit, f
movlw 0x1E ;Num -= 30;
subwf NumL, f
goto Tens2
Tens3
btfss NumL, 4
goto Tens4;
incf Digit, f
movlw 0x0A ;Num -= 10;
subwf NumL, f
goto Tens3
Tens4
movlw 0x0A ;Num >= 10 ?
subwf NumL, w
skpc
return
movwf NumL
incf Digit, f
goto Tens4
Hund1
bsf Digit, 5
btfss NumH, 1
goto Hund2
movlw 5
addwf Digit, f
movlw 0xF4 ;Num -= 500
subwf NumL, f
decf NumH, f
skpc
decf NumH, f
Hund2
btfss NumH, 0
goto Hund3
movlw 2
addwf Digit, f
movlw 0xC8 ;Num -= 200
subwf NumL, f
skpc
decf NumH, f
goto Hund2
Hund3
movlw 0x64 ;Num >= 100 ?
subwf NumL, w
skpc
return
movwf NumL
incf Digit, f
goto Hund3
Thou1
bsf Digit, 6
btfss NumH, 5
goto Thou2
movlw 8
addwf Digit, f
movlw 0x40 ;Num -= 8000
subwf NumL, f
movlw 0x1f
skpc
movlw 0x20
subwf NumH, f
Thou2
btfss NumH, 4
goto Thou3
movlw 4
addwf Digit, f
movlw 0xA0 ;Num -= 4000
subwf NumL, f
movlw 0x0f
skpc
movlw 0x10
subwf NumH, f
goto Thou2
Thou3
btfss NumH, 3
goto Thou4
movlw 2
addwf Digit, f
movlw 0xD0 ;Num -= 2000
subwf NumL, f
movlw 0x07
skpc
movlw 0x08
subwf NumH, f
goto Thou3
Thou4
movlw 0xE8 ;Num >= 1000 ?
subwf NumL, w
movlw 0x03
skpc
movlw 0x04
subwf NumH, w
skpc
return
movwf NumH
movlw 0xE8
subwf NumL, f
incf Digit, f
goto Thou4
TenK1
bsf Digit, 7
btfss NumH, 7
goto TenK2
movlw 3
addwf Digit, f
movlw 0x30 ;Num -= 30000
subwf NumL, f
movlw 0x75
skpc
movlw 0x76
subwf NumH, f
TenK2
movlw 0x10 ;Num >= 10000 ?
subwf NumL, w
movlw 0x27
skpc
movlw 0x28
subwf NumH, w
skpc
return
movwf NumH
movlw 0x10
subwf NumL, f
incf Digit, f
goto TenK2
Nikolai
On Friday, March 10, 2000 James Newton wrote:
{Quote hidden}> Yes.
> Input: 2 registers
> Temp: 1 register
> Output: 1 register
> -------------------
> total: 4 registers
> Required at compile time: 1 subroutine to do something nice with the Output
> value and it can then munch it. For example, you can shift the output
> register out a port pin, leaving behind a zero.
> The only thing that the main routine has to do is call the subroutine for
> each digit of output with a valid number between 0 and 9 (or '0' and '9') in
> the output register.
> Possible improvements for extra credit (not in my code):
> It would be nice if it had an option to output a "." after some number of
> digits passed as a third input.
> It would be nice to optionally skip leading digits that are zero.
> Code that cannot be written for the PIC:
> A general purpose routine that is given a pointer (FSR) to a register
> holding the radix and followed by a count of the number of following bytes
> that contain the binary number to be converted. Output each digit as it is
> developed.
> ---
> James Newton
KILLspamjamesnewtonKILLspam
geocities.com 1-619-652-0593
>
http://techref.massmind.org NEW! FINALLY A REAL NAME!
> Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
> -----Original Message-----
> From: pic microcontroller discussion list
> [
RemoveMEPICLISTTakeThisOuT
MITVMA.MIT.EDU]On Behalf Of Rich Leggitt
> Sent: Thursday, March 09, 2000 14:39
> To:
spamBeGonePICLISTspamBeGone
MITVMA.MIT.EDU
> Subject: Re: How to write code that no one will laugh at [OT]
>> Ok, I have a (probably little and fairly lame) code challenge! [ed: which
>> will probably be ignored 'cause its in Parallax mnemonics and its lame]
> Do we get to destroy the original 16 bit number?
2000\03\10@095409
by
jamesnewton
Same basic idea I had except for storing the state of the conversion in the
output register. I can't do that as I need to add '0' and shift the output
to a serial line. That's why I have a temp register. I thought I might be
able to use the PC as the state by copying a literal table index to W and
doing a sub call. But I wasn't sure that it was worth the extra code size.
I reduced the code size to 76 words by putting the constants in tables (76
words including the tables). I noticed that there are a lot of repeated
values in the table, but I haven't been able to find a way to take advantage
of that in a clean way.
My guess is that your code (and mine) will run in about 100 to 500
instructions. It's nice on the Scenix where 1 instruction is almost 1 cycle
(jmps being the exception).
See
http://techref.massmind.org/microchip/math/radix/b2a-16b5alzs
---
James Newton TakeThisOuTjamesnewtonEraseME
spam_OUTgeocities.com 1-619-652-0593
http://techref.massmind.org NEW! FINALLY A REAL NAME!
Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
{Original Message removed}
2000\03\10@102102
by
jamesnewton
That certainly works and is probably the shortest code. It has the added
advantage of not really needing a temp register (your temp is the output as
well). Its the same idea that Scott Edwards used in his Serout routine but
with a over, under, over, under optimization. Very Nice. See:
www.dontronics.com/convert2.html#serout2
But the 1 loop per digit is just very slow.... uh.... no I just did some
counting and I have 215 instructions worst case for this routine! 60900 is
the worst case right? Wow! I have to test this, but if it really works (and
I don't see why it shouldn't), this is better than Payson's. Its smaller and
is probably faster on the average, and requires no temp register.
Kicks my routine all to heck! Thanks! My boss will think I'm a genius...
<GRIN>
---
James Newton RemoveMEjamesnewton
TakeThisOuTgeocities.com 1-619-652-0593
http://techref.massmind.org NEW! FINALLY A REAL NAME!
Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
{Original Message removed}
2000\03\10@130820
by
Rich Leggitt
> I just did some counting and I have 215 instructions worst case for
> this routine!
Cool, I was guessing much more. If you can figure out how to clean up
those carrys let me know... there MUST be a better way...
-- Rich
2000\03\10@132650
by
Scott Dattalo
|
I added a few things that'll speed it up...
On Fri, 10 Mar 2000, James Newton wrote:
{Quote hidden}> That certainly works and is probably the shortest code. It has the added
> advantage of not really needing a temp register (your temp is the output as
> well). Its the same idea that Scott Edwards used in his Serout routine but
> with a over, under, over, under optimization. Very Nice. See:
> www.dontronics.com/convert2.html#serout2
> But the 1 loop per digit is just very slow.... uh.... no I just did some
> counting and I have 215 instructions worst case for this routine! 60900 is
> the worst case right? Wow! I have to test this, but if it really works (and
> I don't see why it shouldn't), this is better than Payson's. Its smaller and
> is probably faster on the average, and requires no temp register.
>
> Kicks my routine all to heck! Thanks! My boss will think I'm a genius...
> <GRIN>
>
> ---
> James Newton
jamesnewtonEraseME
.....geocities.com 1-619-652-0593
>
http://techref.massmind.org NEW! FINALLY A REAL NAME!
> Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
>
>
> {Original Message removed}
2000\03\10@135213
by
jamesnewton
Nice. Thanks Scott.
The 8 bit to BCD routine is 28 instructions by my count. I have it at
techref.massmind.org/microchip/math/radix/b2bhp-8b3d
and I think it would require another temp... well... no I guess you could
reuse HI. It would also need extra (trivial) code to separate tens and ones.
Summary:
As I don't know the MChip syntax for conditional compilation, I have:
; by Rich Leggitt with tweaks by Scott Dattalo
; given 16 bit data in HI and LO, extract decimal digits
; requires one Output register called temp, HI and LO are destroyed.
; 42? instructions less than 217 (or 199 with known_zero) instructions
executed
clrf temp
skp
sub10k incf temp,f
movlw 10000 & 255
subwf LO,f
;Scott Dattalo says:
;If you have a ram location that's known to be zero, then
;the following [the IF] can be replaced with [the ELSE]
IFNDEF known_zero
movlw 10000 >> 8
skpc
addlw 1 ; this sucks
subwf HI,f
ELSE
rlf known_zero,w
addlw 10000 >> 8
subwf HI,f
ENDIF
bc sub10k ;48/39 inst in loop for 60900 (worst)
output(temp);
movlw 10
movwf temp
add1K decf temp,f
movlw 1000 & 255
addwf LO,f
;Scott Dattalo says:
;If you have a ram location that's known to be zero, then
;the following [the IF] can be replaced with [the ELSE]
IFNDEF known_zero
movlw 1000 >> 8
skpnc
addlw 1
addwf HI,f
ELSE
rlf known_zero,w
addlw 1000 >> 8
addwf HI,f
ENDIF
bnc add1k ;72/63 inst in loop for 60900
output(temp);
;Scott takes over here
clrf temp
movlw 100
skp ;is this a valid macro? I'd write goto $+2 ...
sub100
incf temp,f
subwf LO,f
skpc
goto sub100
decf HI,f
btfss HI,7 ;Check msb instead of carry for underflow.
goto sub100 ;4 inst per loop to 200 then 7 per loop to 900.
;Total 57(?) in loop for worst case
;at this point, HI = 0xff, and 0 <= LO <= 99
output(temp)
movlw 10
movwf temp
add10 decf temp,f
addwf LO,f
bnc add10 ;27 inst in loop for worst case.
output(temp);
output(LO);
return
---
James Newton EraseMEjamesnewton
geocities.com 1-619-652-0593
http://techref.massmind.org NEW! FINALLY A REAL NAME!
Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
-----Original Message-----
From: Scott Dattalo [RemoveMEscottEraseME
EraseMEdattalo.com]
Sent: Friday, March 10, 2000 10:27
To: James Newton
Cc: RemoveMEPICLISTspam_OUT
KILLspamMITVMA.MIT.EDU
Subject: Re: How to write code that no one will laugh at [OT]
Importance: Low
I added a few things that'll speed it up...
2000\03\10@152220
by
Rich Leggitt
|
> ;If you have a ram location that's known to be zero, then
> ;the following can be replaced with
>
> > movlw 10000 >> 8
> > skpc
> > addlw 1 ; this sucks
> > subwf HI,f
>
> rlf known_zero,w
> addlw 10000 >> 8
> subwf HI,f
Scott, you are the MAN! PIC is the only processor I know of that can do a
literal operation on a register but put the result somewhere else.
Requires paradigm shift I obviosuly haven't made yet.
You could maybe use some idle control like SSPCON or INDF for known_zero.
But I may start canonically defining a ZERO file register for just this
kind of thing, it's completely free until out of RAM at which point subtle
optimization isn't the issue :).
> skp ;is this a valid macro? I'd write goto $+2 ...
Um. Well it SHOULD be. :)
> sub100
> incf temp,f
> subwf LO,f
> skpc
> goto sub100
>
> decf HI,f
> btfss HI,7 ;Check msb instead of carry for underflow.
> goto sub100
Good point. What about:
clrf temp,f
movlw 100
incf HI,f ; 1<=HI<=4
goto $+2 ;
sub100 incf temp,f
subwf LO,f
skpnc
decfsz HI,f
goto sub100
>
> ;at this point, HI = 0xff, and 0 <= LO <= 99
Actually, 0 >= LO >= -99. Details, details.
-- Rich
2000\03\10@210940
by
Scott Dattalo
|
Rich Leggitt wrote:
>
> > ;If you have a ram location that's known to be zero, then
> > ;the following can be replaced with
> >
> > > movlw 10000 >> 8
> > > skpc
> > > addlw 1 ; this sucks
> > > subwf HI,f
> >
> > rlf known_zero,w
> > addlw 10000 >> 8
> > subwf HI,f
> Scott, you are the MAN! PIC is the only processor I know of that can do a
> literal operation on a register but put the result somewhere else.
> Requires paradigm shift I obviosuly haven't made yet.
The only credit I deserve is recalling a trick someone else taught me a few
years ago.
{Quote hidden}>
> You could maybe use some idle control like SSPCON or INDF for known_zero.
> But I may start canonically defining a ZERO file register for just this
> kind of thing, it's completely free until out of RAM at which point subtle
> optimization isn't the issue :).
>
> > skp ;is this a valid macro? I'd write goto $+2 ...
> Um. Well it SHOULD be. :)
>
> > sub100
> > incf temp,f
> > subwf LO,f
> > skpc
> > goto sub100
> >
> > decf HI,f
> > btfss HI,7 ;Check msb instead of carry for underflow.
> > goto sub100
>
> Good point. What about:
>
> clrf temp,f
> movlw 100
> incf HI,f ; 1<=HI<=4
> goto $+2 ;
> sub100 incf temp,f
> subwf LO,f
> skpnc
> decfsz HI,f
> goto sub100
I thought about that, but don't you need HI to go negative? I assumed so. Maybe
James will be so kind to run the code through all 65536 test cases in Mplab? :)
> >
> > ;at this point, HI = 0xff, and 0 <= LO <= 99
> Actually, 0 >= LO >= -99. Details, details.
oops, you're right.
Scott
2000\03\10@213713
by
Rich Leggitt
> >
> > clrf temp,f
> > movlw 100
> > incf HI,f ; 1<=HI<=4
> > goto $+2 ;
> > sub100 incf temp,f
> > subwf LO,f
> > skpnc
> > decfsz HI,f
> > goto sub100
>
> I thought about that, but don't you need HI to go negative? I assumed so. Maybe
> James will be so kind to run the code through all 65536 test cases in Mplab? :)
Don't think so, next stage only cares about LO.
-- Rich
2000\03\11@004138
by
Nikolai Golovchenko
[snip]
>> sub10k incf temp,f
>> movlw 10000 & 255
>> subwf LO,f
> ;If you have a ram location that's known to be zero, then
> ;the following can be replaced with
>> movlw 10000 >> 8
>> skpc
>> addlw 1 ; this sucks
>> subwf HI,f
> rlf known_zero,w
> addlw 10000 >> 8
> subwf HI,f
[snip]
I'm sorry, but isn't this an error??
Substraction clears carry bit on borrow. So "rlf known_zero,w" will
not add one to higher byte of the constant on borrow. This scheme may
be used for addition only, I guess.
Nikolai
2000\03\11@023121
by
Rich Leggitt
> I'm sorry, but isn't this an error??
> Substraction clears carry bit on borrow. So "rlf known_zero,w" will
> not add one to higher byte of the constant on borrow. This scheme may
> be used for addition only, I guess.
Umm... [groping for excuse]... we were testing you? Yeah, yeah, that's it.
2000\03\11@124014
by
Nikolai Golovchenko
|
How about this one?
Saves 18 cycles for the first digit, 25 for the second, and 12 for the
fourth. Same(?) for the third. For the case without known_zero it saves
even more. The cost is bigger code.
Conditional compiling directives tested in MPLAB :) James, I can't
figure how you counted executed instructions?
Thanks Scott, your code is very instructive.
;Total execution time:
;worst case: 47 + 66 + 58 + 39 + 2 = 213 cycles(with known zero)
;worst case: 53 + 73 + 58 + 39 + 2 = 226 cycles(without known zero)
;Code size: 68
clrf temp
sub30k
movlw 3
addwf temp, f
movlw low(30000)
subwf Lo, f
IFNDEF known_zero
movlw high(30000)
skpc
movlw high(30000) + 1
subwf Hi, f
ELSE
rlf known_zero, w
sublw high(30000) + 1
subwf Hi, f
ENDIF
skpnc
goto sub30k
add10k
decf temp, f
movlw low(10000)
addwf Lo, f
IFNDEF known_zero
movlw high(10000)
skpnc
movlw high(10000) + 1
addwf Hi, f
ELSE
rlf known_zero, w
addlw high(10000)
addwf Hi, f
ENDIF
skpc
goto add10k
; Output(temp) ;output temp = TenK
;worst case: 10 * 3 + 9 * 3 - 1 = 47 (with known zero)
;worst case: 11 * 3 + 10 * 3 - 1 = 53 (without known zero)
clrf temp
sub3k
movlw 3
addwf temp, f
movlw low(3000)
subwf Lo, f
IFNDEF known_zero
movlw high(3000)
skpc
movlw high(3000) + 1
subwf Hi, f
ELSE
rlf known_zero, w
sublw high(3000) + 1
subwf Hi, f
ENDIF
skpnc
goto sub3k
add1k
decf temp, f
movlw low(1000)
addwf Lo, f
IFNDEF known_zero
movlw high(1000)
skpnc
movlw high(1000) + 1
addwf Hi, f
ELSE
rlf known_zero, w
addlw high(1000)
addwf Hi, f
ENDIF
skpc
goto add1k
; Output(temp) ;output temp = Thou
;worst case: 10 * 4 + 9 * 3 - 1 = 66 (with known zero)
;worst case: 11 * 4 + 10 * 3 - 1 = 73 (without known zero)
clrf temp
sub300
movlw 3
addwf temp, f
movlw low(300)
subwf Lo, f
IFNDEF known_zero
movlw high(300)
skpc
movlw high(300) + 1
subwf Hi, f
ELSE
rlf known_zero, w
sublw high(300) + 1
subwf Hi, f
ENDIF
skpnc
goto sub300
movlw 100
add100
decf temp, f
addwf Lo, f
skpc
goto add100
incf Hi, f
btfsc Hi, 7
goto add100
; Output(temp) ;output temp = Hund
;worst case: 10 * 4 + 5 * 3 + 3 = 59
clrf temp
movlw 30
sub30
incf temp, f
subwf Lo, f
skpnc
goto sub30
movfw temp
rlf temp, f
addwf temp, f
movlw 10
add10
decf temp, f
addwf Lo, f
skpc
goto add10
; Output(temp) ;output temp = Tens
;worst case: 5 * 4 + 5 * 3 + 4 = 39
; Output(Lo) ;output temp = Ones
Nikolai
On Friday, March 10, 2000 James Newton wrote:
{Quote hidden}> Nice. Thanks Scott.
> The 8 bit to BCD routine is 28 instructions by my count. I have it at
> techref.massmind.org/microchip/math/radix/b2bhp-8b3d
> and I think it would require another temp... well... no I guess you could
> reuse HI. It would also need extra (trivial) code to separate tens and ones.
> Summary:
> As I don't know the MChip syntax for conditional compilation, I have:
> ; by Rich Leggitt with tweaks by Scott Dattalo
> ; given 16 bit data in HI and LO, extract decimal digits
> ; requires one Output register called temp, HI and LO are destroyed.
> ; 42? instructions less than 217 (or 199 with known_zero) instructions
> executed
> clrf temp
> skp
> sub10k incf temp,f
> movlw 10000 & 255
> subwf LO,f
> ;Scott Dattalo says:
> ;If you have a ram location that's known to be zero, then
> ;the following [the IF] can be replaced with [the ELSE]
> IFNDEF known_zero
> movlw 10000 >> 8
> skpc
> addlw 1 ; this sucks
> subwf HI,f
> ELSE
> rlf known_zero,w
> addlw 10000 >> 8
> subwf HI,f
> ENDIF
> bc sub10k ;48/39 inst in loop for 60900 (worst)
> output(temp);
> movlw 10
> movwf temp
> add1K decf temp,f
> movlw 1000 & 255
> addwf LO,f
> ;Scott Dattalo says:
> ;If you have a ram location that's known to be zero, then
> ;the following [the IF] can be replaced with [the ELSE]
> IFNDEF known_zero
> movlw 1000 >> 8
> skpnc
> addlw 1
> addwf HI,f
> ELSE
> rlf known_zero,w
> addlw 1000 >> 8
> addwf HI,f
> ENDIF
> bnc add1k ;72/63 inst in loop for 60900
> output(temp);
> ;Scott takes over here
> clrf temp
> movlw 100
> skp ;is this a valid macro? I'd write goto $+2 ...
> sub100
> incf temp,f
> subwf LO,f
> skpc
> goto sub100
> decf HI,f
> btfss HI,7 ;Check msb instead of carry for underflow.
> goto sub100 ;4 inst per loop to 200 then 7 per loop to 900.
> ;Total 57(?) in loop for worst case
> ;at this point, HI = 0xff, and 0 <= LO <= 99
> output(temp)
> movlw 10
> movwf temp
> add10 decf temp,f
> addwf LO,f
> bnc add10 ;27 inst in loop for worst case.
> output(temp);
> output(LO);
> return
> ---
> James Newton
RemoveMEjamesnewtonTakeThisOuT
spamgeocities.com 1-619-652-0593
>
http://techref.massmind.org NEW! FINALLY A REAL NAME!
> Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
> -----Original Message-----
> From: Scott Dattalo [
EraseMEscottspam
spamBeGonedattalo.com]
> Sent: Friday, March 10, 2000 10:27
> To: James Newton
> Cc:
RemoveMEPICLISTKILLspam
MITVMA.MIT.EDU
> Subject: Re: How to write code that no one will laugh at [OT]
> Importance: Low
> I added a few things that'll speed it up...
2000\03\11@124017
by
Nikolai Golovchenko
Hello Rich,
This is how to fix it:
rlf known_zero,w ;w=0 on borrow or 1 on no borrow
sublw 10000 >> 8 + 1 ;w = 10000 >> 8 + 1 - w
;w = 10000 >> 8 + 1 on borrow
;w = 10000 >> 8 on no borrow
subwf HI,f
Nikolai
On Saturday, March 11, 2000 Rich Leggitt wrote:
>> I'm sorry, but isn't this an error??
>> Substraction clears carry bit on borrow. So "rlf known_zero,w" will
>> not add one to higher byte of the constant on borrow. This scheme may
>> be used for addition only, I guess.
> Umm... [groping for excuse]... we were testing you? Yeah, yeah, that's it.
2000\03\11@152018
by
Rich Leggitt
On Sat, 11 Mar 2000, Nikolai Golovchenko wrote:
> This is how to fix it:
> rlf known_zero,w ;w=0 on borrow or 1 on no borrow
> sublw 10000 >> 8 + 1 ;w = 10000 >> 8 + 1 - w
> ;w = 10000 >> 8 + 1 on borrow
> ;w = 10000 >> 8 on no borrow
> subwf HI,f
Ya, this also occurred to me this morning... strange, it is a conjunction
of two AFAIK unique picisms: do something to a variable but put the result
in the accumulator, and subtract the accumulator FROM a constant.
Unique, but to good effect. Consider subtraction of 16-bit constant from
memory:
PIC = 5 cycles/70 bits (14 bit core):
movlw low(const)
subwf LO,f
rlf ZERO,w
sublw high(const)+1
subwf HI,f
8051 = 6 cycles/96 bits:
mov a,LO
sub a,#low(const)
mov LO,a
mov a,HI
subc a,#high(const)
mov HI,a
68HC11 = 12 cycles/72 bits:
ldd HILO
subd #const
std HILO
68000 = 12 cycles/48 bits:
subi.w #const,HILO
Accidental? Can't be. Does anybody know where the pic instruction set came
from?
-- Rich
2000\03\11@164515
by
Dmitry Kiryashov
Hi Scott.
> > movlw 10000 >> 8
> > skpc
> > addlw 1 ; this sucks
> > subwf HI,f
>
> rlf known_zero,w
> addlw 10000 >> 8
> subwf HI,f
rlf known_zero,W
sublw (10000>>8)+1
subwf Hi,F
probably would be more correct...
{Quote hidden}> ; similarly:
>
> > movlw 1000 >> 8
> > skpnc
> > addlw 1
> > addwf HI,f
>
> rlf known_zero,w
> addlw 1000 >> 8
> addwf HI,f
Agreed. ;)
WBR Dmitry.
2000\03\13@111444
by
jamesnewton
I count rapidly and inaccurately. <GRIN>
Uh... Are you saying cycles when you mean executed instructions? Or are you
running this on a Scenix chip? The PIC is, what, 4 cycles per instruction?
Or am I confused as usual?
After recounting, I have 41 instructions and less than 201 instructions
executed (not cycles) for the known zero case of Rich and Scotts code with
your and Dimitrys bug fix and 219 without. And that is worst case. It would
be something between 41 and 201/219 (121/130?) on the average where your or
my code would be something closer to 145 on the average.
I think you and I are out of the running with the successive approximation
method. The 1 digit at a time is just faster (and smaller).
---
James Newton jamesnewtonSTOPspam
spam_OUTgeocities.com 1-619-652-0593
http://techref.massmind.org NEW! FINALLY A REAL NAME!
Members can add private/public comments/pages ($0 TANSTAAFL web hosting)
{Original Message removed}
More... (looser matching)
- Last day of these posts
- In 2000
, 2001 only
- Today
- New search...