Date : Tue, 24 Nov 2009 00:00:24 +0000
From : rs423@... (Mick Champion)
Subject: Quine
Michael Firth wrote:
> Mick Champion wrote:
>
>> Jonathan Graham Harston wrote:
>>
>>
>>>
>> Thanks. I've done a few programs in assembly language, but never got my
>> head around things like LSR (logical shift right).
>>
> LSR = Logical Shift Right, equivalent to a divide by 2
> ASL = Arithmetic Shift Left, equivalent to a multiply by 2
>
> The main difference between LSR/ASL and ROR/ROL is what happens with the
> carry.
>
> With the ROx functions, the LSB or MSB becomes the carry, and the carry
> becomes the LSB or MSB. However, with LSR and ASL, the bit that is
> shifted out becomes the carry, but a zero is shifted in, rather than the
> old carry.
>
Ah. Yes. Just experimented with them (LSR & ASL). So it does. I think I
may have got confused or rather mixed them up with with the ROR and ROL
commands. Not quite sure what the point or those are..... yet.
>
>> In your decode
>> listing, you do this 4 times. If I wanted to multiply, off the top of my
>> head, I'd do something like
>>
>> CLC
>> LDA byte1
>> LDX #0
>> .loop
>> ADC byte1
>> STA byte1
>> BCC a
>> INC byte2
>> .a
>> INX
>> CPX#4
>> BNE loop
>>
>>
>>
>> Am I missing something?
>>
>>
>>
>
> You can use ASL to multiply, for example:
>
> ASL A
> STA temp
> ASL A
> ASL A
> CLC
> ADC temp
>
> Is equivalent to a multiply by 10.
>
The penny has dropped at last, great. I can see when using one byte,
this could be VERY useful, but using two bytes (multiplied by 5) my code
seems quite long,
LDA &4010 // load and save original values
STA &4012
LDA &4011
STA &4013 //
CLC
ASL &4010 // multiplied by 2
JSR carry
ASL &4010 // multiplied by 4
JSR carry
LDA &4010 // add original value to make 5
ADC &4012
STA &4010
LDA &4011
ADC &4013
STA &4011
RTS
.carry
LDX#0
BCC carry2 // check carry and
LDX#1 // make X=1 if set
.carry2
ASL &4011 // shift hi byte left then
CLC
TXA // add the carry stored in X after the shift
ADC &4011
STA &4011
RTS
whereas ;
CLC
LDA &4010 // save multiplier
STA &4012
LDA &4011
STA &4013
LDX#0
.a
CLC
LDA &4010 // keep adding multiplier
ADC &4012 // until X equals reqd. multiple
STA &4010
LDA &4011
ADC &4013
STA &4011
CPX#4
BNE a
RTS
seems to shorter code wise.I'm sure there must be a quicker, tidier way
to do this.
> A common construct to see in BBC (and probably other 6502) assembler is
> 4 ASLs or LSRs, which do a divide or multiply by 16, useful for moving
> data between the nibbles of bytes.
>
But don't both ASL and LSR shift in zeros? Perhaps you mean ROL and ROR?
Aha, yes. So if you wanted you check nibble 2 of a byte, ROR:ROR, then
check the carry flag as it will be set if bit is a 1 or clear if a zero?
Does that sound right? I suppose you'd have to remember to shift it back
again or else the program would soon lose the plot. There there's how to
set the bits. I suppose that would be the byte AND a whole number? Hmmm.
> Another common construct is to combine ASLs and ROLs to be able to
> multiply with variables bigger than 8 bits - an "ASL loc" followed by a
> "ROL loc+1" does a 16 bit multiply by 2.
>
Now I'm lost again. I thought that both ROL and ASL use the carry flag
for output only.
Thanks,
Mick