Re: Assy question - I challenge you to do better!

From: Spiro Trikaliotis (Trik-news_at_gmx.de)
Date: 2001-03-16 09:12:47

Hi,

> The routines are not out of context because they are
> not part of a larger program. I typed them in exactly
> as they are presented in the book, except the comments
> are mine. The only command I left out of each code
> snippet was the BRK at the end of each.

I know, I'm an owner of this book, too. ;-)

> Besides, its ABSURD to assume that SED is the default
> condition for the entire program. NO-ONE programs this
> way. Even Leventhal recommends keeping D clear outside
> of subroutines! For that reason I say its QUITE FAIR
> to include SED and CLD in the cycle count.

I'm not so sure for this. For example, in a program dealing with monetary
values, it might be the "normal" thing to have decimal mode. Think: That we
are not used with the decimal mode not mean that it is not reasonable to use
this. With mainframes (of these times), most of the times, you were working
with the decimal mode.

Processors before the 6502 mostly didn't have a decimal flag, they had extra
commands to do decimal arithmetic, which corrected the value afterward the
calculation. I believe MOS thought that it would be very handy to have this
mode, because you would not always be forced to correct the value after it
is calculated. So, I would say that MOS indeed thought it would be a big
advantage to be able to write most parts of a program in decimal mode -
else, they would not have included this mode, which, as for as I know, no
other processor (except the 65xx series) has!

> Here're two sample routines I cooked up to test your
> second statement:
[...]

> ; TRY DECIMAL MODE ALGORITHM
[...]

You know your error?

[...]
> JSR MAKEDIG ; 6 CYCLES
> STA $FB ; 3 CYCLES
> TXA ; 2 CYCLES
> AND #$0F ; 2 CYCLES

> ; 2 ITERATIONS FOLLOWING CODE
> MAKEDIG CLC ; 2x2=4 CYCLES
> ADC #$90 ; 2x2=4 CYCLES
> ADC #$40 ; 2x2=4 CYCLES
> CLD ; 2x2=4 CYCLES
  ^^^
Here, you're leaving decimal mode. In the second iteration, you don't have
it anymore!

> STA $FC ; 3x2=6 CYCLES
> RTS ; 6x2=12 CYCLES
> ; 59 CYCLES TOTAL

> Looks like you were correct Spiro!

Not any more with the error!

> Now, I suppose I can further optimise it by removing
> the subroutine calls and using straight-line code:

[...]

> AND #$0F ; *Can this be omitted?
> CLC ; **IS THIS EVEN NECESSARY?
> ADC #$90
> ADC #$40
> STA $FC
> CLD
> ; 36 cycles. BLAZING FAST!

> * I dont' think its really necessary to mask out the
> high nybble here. Since there is no CoMParison to do,
> the extra nybble should just overflow thru the Carry
> and out into the binary ether, right???

I don't think so! The ADC #$90 is for generating an additional carry in case
we have a value from A - F, but not generate in in case we have a value from
0 to 9. Additionally, both additions want to add $90+$40 = $(1)30 to your
value, so you end up in the range $30-$39 OR $41-$45.

Think of the following case:

You have $28 to convert. The first ADC #$90 now generates a carry, since
$28+$90 = $118 (in decimal mode). So, the second ADC #$40 generates
$18+$40+C = $59. Observe that our result is not only out of range, even it's
lowest nibble is not right because the carry was set wrong!

> ** I'm pretty damn sure that the first instance of ADC
> #$40 will eat any carry. Thus, C is already clear for
> the low nybble.

NO! If your initial value was in the range 0-9, the ADC #$40 will surely
GENERATE a carry, because the first ADC generated a value in the range
$90-$99. If your initial value was in the range A-F, the ADC #$40 will not
generate a carry, because the first ADC #$90 generated a value in the range
$100 to $104.

> ASIDE - I'm inexperienced with 6502 decimal mode
> operations. I was SHOCKED to discover that in decimal
> mode $0A is treated as 10 'ones' units!  :-O

Well, simplified speaking, think of the decimal mode as adding another ADD:
If a nibble of the result from the first ("real") addition is in the range
"A"-"F", then add 6 to that nibble (that goes for both nibbles). Because of
this strategie, the processor cannot determine of on $0A, for example, was
generated by the first ("real") addition, or was there as input.

Spiro.

-
This message was sent through the cbm-hackers mailing list.
To unsubscribe: echo unsubscribe | mail cbm-hackers-request@dot.tml.hut.fi.

Archive generated by hypermail 2.1.1.