11

In the 80s, the two great 16/32-bit desktop CPU architectures were the x86, used in the IBM PC and compatibles, and the 68000, used in the Amiga, Atari ST, Macintosh, early UNIX workstations and really most things that were not trying to run MS-DOS.

With the rapid growth of MS-DOS, there inevitably developed an interest in running it on 68000 machines anyway, either by providing an x86 second processor or by software emulation. (Both of those solutions were tried on the Amiga, for example.)

One fundamental problem with this is that the x86 is little endian and the 68k is big endian, which would cause chaos every time you tried to transfer binary data between the two.

It occurs to me to wonder whether you could add any kind of glue logic to make the 68k run little endian, e.g. by swapping byte lanes in the data bus.

But it seems to me there is going to be a fundamental problem with that. You could swap the two bytes in a 16-bit transfer. But the 68k transfers 32-bit numbers as a pair of 16-bit chunks, in sequence. The glue logic would have no way of knowing whether a pair of 16-bit transfers, one after the other, were meant to be the two halves of a 32-bit word (in which case they would need to be swapped) or separate words (in which case they would need to be kept as is). I'm guessing that's the reason I never heard of anyone making the 68k run little endian.

(The 68020, with its 32-bit data bus, would be an easier proposition. But by the time that chip was widely used, I think people had mostly given up on running MS-DOS on anything other than fully IBM-compatible hardware.)

Am I missing anything, or is that indeed why no one ever did run the 68k little endian?

6
  • 1
    There is actually the fundamental problem but not the one you mentioned (as THAT is fixed trivially by inverting A1 address line): if you blindly swap bytes in every 16bit word, binary data that was previously sequence of bytes gets also swapped. As far as I can suggest, one can map LE memory in two areas for 68k: byte-swapped and NON-byte-swapped. If one needs to read 32bit words, he goes to swapped area, otherwise (8bit quantities) to unswapped.
    – lvd
    Commented Jun 29, 2020 at 11:39
  • 1
    @lvd I believe the 68000 does make it possible for glue logic to tell whether it is transferring a byte or a 16-bit word. I think it's only 32-bit words that would still need a software SWAP instruction.
    – rwallace
    Commented Jun 29, 2020 at 15:44
  • 1
    of course it does, but this does not solve the fundamental problem. Imagine there is 16-bit hardware register full of bit flags and bitfields that one wants to access as a whole. Hardware then should not do any byteswap, to keep bit 15 of the register in bit 15 of data bus, etc. If, alternatively, that register reveals some bytestream by successive readings of 16bit quantities, the byteswap, instead, must be then done. So as a whole, there is no simple hardware-only solution to the endianness problem.
    – lvd
    Commented Jun 29, 2020 at 16:37
  • Not all binary formats are little endian just because x86 is popular. IP address for example is big endian in its binary format forcing x86 to implement endian swap routine every time you access the internet. The problem is not endianness. The problem is poorly documented binary formats. There is zero advantage to either being big endian or little endian.
    – slebetman
    Commented Jun 30, 2020 at 4:11
  • 1
    The real fundamental problem with big endian architectures was when people started running Linux on 68k and PowerPC. Badly written C programs did not read binary formats from disk or the network correctly instead assuming that data on disk is aligned with data in RAM. This problem has mostly disappeared mainly due to the fact that not many programs written by inexperienced programmers are written in C/C++ these days but are mostly written in Java, Ruby, Python, Node.js etc which automatically take care of endianness for you because the language itself has an endian preference.
    – slebetman
    Commented Jun 30, 2020 at 4:15

3 Answers 3

12

Swapping byte lanes on the physical bus would, in any case, only have an effect on naturally aligned data in memory, which happened to be the same width as the bus. Swapping the lanes of a 16-bit bus doesn't solve the problem for 32-bit data, nor on a 32-bit bus for 64-bit or 80-bit data (the latter being associated with floating point). So that is not a very effective solution in general.

The basic problem is one that has to be solved when interchanging file formats between computers, and is independent of whether a second CPU is installed. An x86 CPU processing Internet packets (which are big-endian) has to do this, while a 68K CPU processing some x86-original formats, also has to. Usually the endianness of the data would be fixed using a software routine before processing began in earnest. The following sequence will reverse a 32-bit word in D0 on the 68K:

ROL.W #8,D0
SWAP.L   D0
ROL.W #8,D0
6
  • 3
    Note that early (at least; I lost contact at the R3000) MIPS processors could go either way, by startup config, possibly wired, choice. but this was comparatively straightforward since the only place byte sex shows up is in memory access, which is limited to LOAD and STORE in the MIPS architecture.
    – dave
    Commented Jun 28, 2020 at 17:25
  • 2
    MIPS can still switch endianness, as can ARM (at least some implementations) and POWER. Commented Jun 28, 2020 at 17:59
  • 2
    @another-dave Both PowerPC and recent versions of ARM have load and store byte-reversed instructions.
    – Chromatix
    Commented Jun 28, 2020 at 18:10
  • 1
    SWAP.L can be written SWAP, as there is no SWAP.W Commented Jun 28, 2020 at 18:37
  • 4
    @Jean-FrançoisFabre I wrote it verbosely for clarity, since mixed length instructions are being used on the same register.
    – Chromatix
    Commented Jun 28, 2020 at 20:56
7

Since you mentioned the Amiga in your question, it ought to be relevant as to how this problem was solved efficiently on that system.

As I understand, the "glue" logic for the Bridgeboards consisted mainly of 128KiB of dual-ported RAM accessible by both the Intel CPU on the Bridgeboard and the Amiga's 68K. This would be sufficiently large to buffer whole video frames and virtual hard drive accesses, and the dual-port hardware eliminates the need for low-level synchronization.

The Janus Library (Amiga drivers for the Bridgeboard) seems to have managed transfers as a bidirectional FIFO in the dual-port RAM. So, really, just a byte stream to which both CPU's had Read/Write access. As such, the endianess is easily solved in software by just following a convention - much as network communications solves it by convention when they transfer byte streams between hosts with different native data formats.

However, I do recall hearing at some point that the Bridgeboard did include some hardware endianess assistance, so that neither CPU's interface drivers would be forced to waste cycles dealing with data that wasn't native. Of course, they would have still needed some software convention for transfer of 32-bit data. But, given the 16-bit limitation of the Zorro II bus, and all versions of the Commodore Bridgeboard having max. 16-bit data bus Intel CPU's, that issue could have been avoided in the driver software.

5

This take a little more circuitry than the OP, in that the byte-swapper has to make use of the Function Code bus lines (FC0, FC1 and FC2) to distinguish between data transfers and instruction fetches. Bytes should only be swapped for data transfers; applying byte-swapping to instructions will wreck the execution of software.

1
  • 1
    It's simple to distinguish between instruction fetches and data transfers. The 68000 bus contains Function Code outputs FC[2:0] that identify each transfer as one of: User Data; User Program; Supervisor Data; Supervisor Program; CPU Space.
    – TonyM
    Commented Jun 28, 2020 at 19:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .