[comp.sys.apple] The last word on MSB/LSB

ST702174@BROWNVM.BITNET (Dan Bornstein) (11/28/88)

To Gadi and others:

It seems there has been much confusion on the matter of MSB/LSB order on the
65xx series. I have been programming in machine language (that is, *300: xx xx
xx etc), mini-assembler, and assembler for quite some time, and I should hope
that I know what I'm talking about:

In the 65xx, in all 2-byte address instructions (LDA addr, STA addr, etc.), the
address is encoded Least Significant Byte first. For example, to encode LDA $12
34, the hex is AD 34 12. In all indirect instructions (zp) (zp,x) (zp),y
(addr) [zp] [zp,x] [zp],y the address referred to starts with the Least
Significant Byte. For example, if you wanted to zero out a bank in 65816 using
the [zp] addressing mode, you might have a piece of code that looks like this:

       LDA #$04        We want to clear bank 4
       STA $02
       STZ $00         Start at location 0
       STZ $01
       LDA #$00
loop   STA [$00]
       INC $00         Note that $00 and $01 are being incremented and not $02
       BNE loop        which is highest in memory.
       INC $01
       BNE loop
       RTS

In the 65816, with long memory, anything that deals with memory uses a LSB-
first approach. For example, INC $0400 will increment location $0400 and then
location $0401 if $0400 carries over. If you don't believe me, try this simple
program which continually increments the first two screen locations. Note that
the leftmost byte increments more rapidly than the one to its right, proving my
point.

0300: CLC            set up the processor mode
0301: XCE
0302: REP #$30
0304: LDY #$0100     a short delay
0307: DEY
0308: BNE $0307
030A: INC $0400      the fateful instruction
030D: BRA $0304      jump back

Of course, you can also look it up in any 65xx book to see that I'm not jiving
you.

FINALLY: A statement of "It makes sense that way in the 65xx":
The 65xx is notorious for having instructions that use chunks of memory of
different lengths: There are zero-page addresses (1 byte), regular addresses
(2 bytes), long addresses (3 bytes), literals (1 byte), long literals (2 bytes)
the stack pointer (1 or 2 bytes), etc. In a situation like this, it would seem
to make sense to have as much of an address in an invariant relative location
as possible. As it stands, if one wanted to store $654321 in a certain
location, it would be stored as 21 43 65. $4321 would be stored 21 43. $21
would be stored (of course) 21. Note that the LSB is in the same relative
location each time. If the 65xx were MSB first, then it would have to change
its internal architecture for different addressing modes. (In a 2-byte fetch,
it would have to make the LSB second, not first, etc.) The way it is now, the
processor only needs to determine HOW MANY bytes to fetch, (Yes, this is
simplifying a bit.) which makes the processor's life a lot easier.

If you would like to refute this, please be a machine language programmer or
quote from a book or something like that. Thanx.

-dan

gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/29/88)

In article <8811271555.aa16183@SMOKE.BRL.MIL> ST702174@BROWNVM.BITNET (Dan Bornstein) writes:
>If the 65xx were MSB first, then it would have to change its internal
>architecture for different addressing modes.

ONLY if you assume that it fetches bytes in ascending address order.
It in fact a time sequence were involved (which it is NOT), then
indeed LSB first has the advantage you cite.

This is why I harp on using proper terminology instead of "first"!

Dave Lyons posted the most careful description so far.