6

I asked a similar question about the Intel 8080 to which I guessed the answer would probably be yes, because later Intel CPUs did fully handle unaligned access.

I am less sure about the Motorola 6800, because several of the inventors went on to invent the MOS Technology 6502, which in some contexts treats page boundaries as special. But there are differences between the two; for example, the 6800 has a 16-bit stack pointer, whereas the 6502 has an 8-bit stack pointer. Perhaps this is also a difference.

So:

The 6800 is referred to as an 8-bit CPU because it has an 8-bit data bus, but there are a number of cases where it must perform 16-bit memory access, for example when reading or writing a 16-bit register, or the 16-bit program counter when performing subroutine call or return.

I assume it supports unaligned access, i.e. the address is not required to be even.

Does it support fully unaligned access in all cases, i.e. no requirement that both bytes be in the same page? For example, if you try to write a 16-bit register to address $7fff, will the second byte be written to $8000? Or if the stack pointer was set to $8001 and you perform a subroutine call, will the return address be written to the addresses $8000 and $7fff?

chicks
  • 397
  • 1
  • 4
  • 15
rwallace
  • 60,953
  • 17
  • 229
  • 552
  • 1
    That would be a pretty useless stack pointer, wouldn't it? – tofro Nov 08 '20 at 14:00
  • @tofro Why do you think so? I wrote a fair bit of code on the 6502, and never had a problem with the stack. – rwallace Nov 08 '20 at 14:19
  • 1
    @rwallace Then why assume there are problems with other CPUs? Especially as the 6502 is the outlier here with a stack limited to a singel page (due it's internal paged structure). – Raffzahn Nov 08 '20 at 14:30
  • 3
    Similar question, similar answers... :) To prevent other attempts, let me state: The same answer is valid for 6502, Z80, 6809, 1802, 8085 and other 8-bit CPUs... – Martin Maly Nov 08 '20 at 14:35
  • 1
    @MartinMaly Not quite true. In particular the 6502, aside from the explicit zero-page addressing modes and one-page stack, has one case where an attempt to access a 16-bit word across a page boundary will cause the second addressed to wrap around the beginning of the page. – rwallace Nov 08 '20 at 14:55
  • 1
    You could use visual 6800 to verify what's happening. – Kelvin Sherlock Nov 08 '20 at 16:02
  • 1
    @rwallace: I also find myself wondering how hard it would have been or how much it would have cost on the 6502 to mask off the LSB of the address operand used in (zp,x) and (zp),y addressing modes, and used to select two more addressing modes--perhaps (zp) and (zp,x)|1 [force the LSB of the address to be set]. Requiring that pointers in zero-page be aligned at even addresses wouldn't have been much of a limitation, but it would have made (zp,x) addressing mode immensely more useful for processing 16-bit data. Adding such a design feature after the fact would have broken... – supercat Nov 08 '20 at 18:01
  • 1
    ...a lot of code which, by happenstance, places a lot of zero-page pointers at odd addresses (e.g. many MS-BASIC versions) but the revised (zp,x) addressing mode would have been awesome. – supercat Nov 08 '20 at 18:03
  • 1
    @supercat It would have meant a complete different and way more complex decoding. No way they would have done that for such a minor advantage. – Raffzahn Nov 08 '20 at 20:29
  • 1
    @Raffzahn: It could have been implemented by adding a "set" and "clear" signal for the main latched address LSB and a separate latch to grab D0. When fetching the operand byte of any (ind,x) instruction, force-clear the LSB of the address latch and grab D0. While fetching the MSB of the target address, do a force-set of the LSB of the address latch if the latched D0 had been set. Given the relative ease of adding an extra async set/clear signal to an NMOS latch, the amount of circuitry would have been fairly slight. – supercat Nov 08 '20 at 21:41
  • 1
    @Raffzahn: Two transistors plus pull-ups for a passive latch. A transistor to clear that latch at the start of an instruction, and two to set it during the second cycle based on data bus bit 0. Two transistors transistor to clear bit 0 of the temporary latch during the third cycle of (zp,x) or (zp),y, and three to set it during the fifth cycle of (zp,x) if the new latch is set. So my my count ten transistors and two passive pull-ups. What required complexity am I not seeing? – supercat Nov 08 '20 at 22:26

2 Answers2

8

No alignment is necessary. There is no paging of any kind either. Any 16-bit register can be stored to or retrieved from any memory address, odd or even.

There is one thing though, if the accessed memory addresses are in the range from $0000 to $00FF, these can be accessed by using direct memory addressing opcodes that only take 8-bit memory address as parameter, instead of using extended addressing mode opcodes that take the full 16-bit memory addresses. So accessing variables in the zero page is slighty faster than variables not in zero page.

Examples:

Storing a 16-bit register into memory:

LDX #$1234
STX $7FFF

First line loads register X with immediate value of $1234 and the second line stores the register X into memory address $7FFF. So it writes $12 to address $7FFF and $34 to address $8000.

Jumping to a subroutine:

LDS #$7FFF
JSR XYZ

First line sets the stack pointer to $7FFF, and the second line jumps to subroutine XYZ, which stores low byte of PC to address $7FFF and high byte of PC to address $7FFE, and finally the stack pointer would be $7FFD.

Justme
  • 31,506
  • 1
  • 73
  • 145
  • 1
    Out of curiosity, can you load a 16-bit register from $FF, and does it wrap around to $00 or $0100? – user253751 Nov 09 '20 at 11:09
  • 1
    @user253751 This certainly happened for certain 6502 variants using zero page accesses (wrap around from 0xFF to 0x00) because a zero page address is by definition 8 bits and the high order 8 bits are simply held low for the accesses (the 65151 in my case; I remember the datasheet warning). – Peter Smith Nov 09 '20 at 14:23
  • 1
    @user253751: The 6502 doesn't have any 16-bit registers. When the 6502 fetches a 16-byte address for use with (zp,x) or (zp),y mode and the low byte is at $FF, the high byte will be fetched from address zero. The behavior of JMP (abs) varies between the NMOS 6502 and CMOS variants. The NMOS versions take five cycles, and increment the low byte of the supplied address between the first and second fetches of the jump target. The NMOS versions always take six cycles, and increment the entire address. I would think the easiest way of handling JMP (ind) would have been to treat it... – supercat Nov 09 '20 at 21:13
  • 1
    ...much like a JMP except that the actions after the second and third cycles would be repeated after the fourth and fifth, so after cycle 2 the data bus value would be placed into a holding register while PC is incremented; after cycle 3, the holding register would be copied to PC and address low, while the data bus would be copied to PCH and address high, then after cycle 4 the cycle-2 actions would be repeated, and after cycle 5 the cycle-3 actions would be repeated. No versions of the 6502 seem to do that, however. – supercat Nov 09 '20 at 21:17
5

For the 6800 the same basic considerations as for all other CPUs are valid, as already mentioned in the 8080 answer is as well valid here:


Background

The question may stem from a mixup between data size requirements and data bus size. Alignment issues can only come up with designs that have a finer address granulation than the external data bus and accessing a data item sized of multiple address units, i.e. a CPU with byte addressing but a multiple byte wide data bus accessing data wider than a single byte - like a 68020 (byte addressing, 4 byte wide data bus) accessing a 16 bit word.


The 6800 is, like the 8080 a plain 8 bit CPU with a 16 bit address path. Motorola CPUs are much like taken literally from a beginners lecture - middle of the road, as vanilla as it can be :)

So no, like with the 8080, pointers can hold any address and word access (essentially loading pointers) can be done from such.

Raffzahn
  • 222,541
  • 22
  • 631
  • 918