The Motorola 68000 is a complex instruction set computer microprocessor, the first member of a successful family of microprocessors, which were all mostly software compatible.
- Motorola 68008
- Motorola 68010
- Motorola 68012
- Motorola 68020
- Motorola 68030
- Motorola 68040
- Motorola 68060
- Motorola CPU32
- Motorola Coldfire
The 68000 was a clever compromise. When the 68000 was introduced, 16-bit busses were really the most practical size. However, the 68000 was designed with 32-bit registers and address spaces, on the assumption that hardware prices would fall. To address the perceived markets, the actual 68000 was designed in three forms. The base-form had a 24-bit address, and a 16-bit data bus. The short form, the 68008, had an 18-bit address (possibly 19 or 20 bits, at least one firm addressed 512KBytes with 68008s), and an 8-bit data bus. A planned future form (later the 68020) had a 32-bit data and address bus.
Notable design wins include the Macintosh, and the original Sun Microsystems and SGI UNIX machines. 68000 derivatives persisted in the UNIX market for many years, because the architecture so strongly resembles the Digital PDP-11 and VAX, and is an excellent computer for running "C" code. The 68000 eventually saw its greatest success as a controller. Thousands of HP, Printronix and Adobe printers used it. Its derivative microcontrollers, the CPU32 and Coldfire processors have been manufactured in the millions as automotive engine controllers. It also sees use by medical manufacturers and many printer manufacturers because of its low cost, convenience, and good stability. As of 2001 the Dragonball versions of the processor are used in the popular Palm series of PDAs from Palm Computing and Handspring's Visor, though the architecture is being phased out in favor of the ARM processor core.
Initial samples of the 68000 were released in 1982, and competed against the Intel 8086 and Intel 80286 with some success. Initial clock rates were a then-blisteringly fast 8MHz, with a rather slow eight to ten clocks per instruction. However, the instructions did more than Intel processors. Motorola ceased production of the 68000 in 2000, although derivatives, notably the CPU32 family, continue in production. As of 2001, Hitachi continued to manufacture the 68000 under license.
The CPU had 8 general-purpose data registers, and 8 address registers. The last address register was also the standard stack pointer, and could be called either A7 or SP. This was a good number of registers in many ways. It was small enough to make the 68000 respond quickly to interrupts (because only 16 had to be saved), and yet large enough to make most calculations fast.
Having two types of registers was mildly annoying at times, but really not hard to use in practice. Reportedly, it allowed the CPU designers to achieve a higher degree of parallelism, by using an auxiliary execution unit for the address registers.
The 68000 comparison, arithmetic and logic operations set bits in a status register to record their results for use by later conditional jumps. The bits were "Z"ero, "C"arry, e"X"tend, and "N"egative. The eXtend bit deserves special mention, because it was separated from the Carry. This permitted the extra bit from arithmetic, logic and shift operations to be separated from the carry for flow-of-control and linkage.
The designers attempted to make the assembly language was orthogonal. That is, instructions were divided into operations and address modes. Almost all address modes were available for almost all instructions. Many programmers disliked the "near" orthogonality, while others were grateful for the attempt.
At the bit level, the person writing the assembler would clearly see that these "instructions" could become any of several different op-codes. It was quite a good compromise because it gave almost the same convenience as a truly orthogonal machine, and yet also gave the CPU designers freedom to fill in the op-code table.
The minimal instruction size was huge for its day, 16 bits! Furthermore, many instructions and addressing modes added extra words on the back for addresses, more address-mode bits, etc.
Many designers believed that the M68000 architecture had compact code for its cost, especially when produced by compilers. This belief in more compact code led to many of its design wins, and much of its longevity as an architecture. Most embedded system designers are acutely aware of the costs of memory. This belief (or feature, depending on the designer) continued to make design wins for the instruction set (with updated CPUs) up until the ARM introduced compressed op-codes that were more compact.
The CPU, and later the whole family, implemented exactly two levels of privilege. User mode gave access to everything except the interrupt level control. Supervisor privilege gave access to everything. An interrupt always became supervisory. The supervisor bit was stored in the status register, and visible to user programs.
A real advantage of this system was that the supervisor level had a separate stack pointer. This permited a multitasking system to use very small stacks for tasks, because the designers did not have to allocate the memory required to hold the stack frames of a maximum stack-up of interrupts.
The CPU recognized 8 interrupt levels. Levels 0 through 7 were strictly prioritized. That is, a higher-numbered interrupt could always interrupt a lower-numbered interrupt. In the status register, a privileged instruction allowed one to set the current minimum interrupt level, blocking lower priority interrupts. Level 7 was not maskable. Level 0 could be interrupted by any higher level. The level was stored in the status register, and was visible to user-level programs.
The "exception table" (interrupt vector addresses) were fixed at addresses 0 through 1023, permitting 256 32-bit vectors. The first vector was the starting stack address, and the second was the starting code address. Vectors 3..15 were used to report various errors: bus error, address error, illegal isntruction, zero division, CH1 & CHK2 vector, privilige violation, and some reserved vectors that became Line 1010 emulator, line 1111 emulator, hardware breakpoint. Vector 24 started the real interrupts: spurious interrupt (i.e. it wasn't properly hand-shaken), and level 1 .. level 7 autovectors, then the 15 TRAP vectors, then some more reserved vectors, then the user defined vectors.
The interrupt controller was originally a separate IC, the 68901. This chip performed a rather complicated dance on the bus to translate the seven pull-down interrupt lines into vectored interrupts (level 1 through 7). The 68901 also provided a basic UART and (if memory serves) a periodic interrupt timer. The Motorola 68901 had a number of severe defects, including the ability to lose the highest-priority interrupt if it and the clock interrupt happened within some window of each other. The Mostek part was superior.
The fixed exception table was screamingly annoying for hardware designers. One wants a ROM bootstrap, but then once the OS is up, one wants installable vectors. A lot of effort went into circumventing the fixed vectors.
Another problem was the "privilege" logic. The designers had clearly planned on having a minimal, but adequate two-tiered security system to support something like a UNIX kernel. This would limit the ability of user programs to access hardware and interrupts. The design had security holes, which were fixed in later processor models.
The 68000 was also unable to correctly return from an exception on a failing memory access, a crucial feature to enable true virtual memory. To simulate unlimited RAM, one wants to interrupt when a memory access fails, and then the interrupt routine will allocate a block of real RAM, and read a piece of data on disk into it. Several companies did succeed in making 68000 based Unix workstations with virtual memory that worked, so there must have been a way. But they upgraded to the 68010 as quickly as possible,
A more subtle problem was that the 68000 could not easily run a virtual image of itself without simulating a large number of instructions. This problem persists in many modern versions of the architecture, which is rarely used in these applications. This lack caused the later versions of the Intel 80386 to win designs in avionic control, where software reliability was achieved by executing software virtual machines.
In the next major revision, the 68010, most of these problems were fixed.
The standard address modes were:
A data register, e.g. "D0"
an address register, e.g. "A6"
a memory location, a symbolic name in the assembler: "some_address"
an "immediate" value stored in the instruction, e.g. "#400"
access a 16-bit offset added to an address register, e.g. "16(A0)"
access the memory at an address register, and then increment it, "(A0)+"
decrement the address register, and access the memory at that address, e.g. "-(SP)"
access memory at an offset from the sume of an address register and data register 12(D0.W,A0)
access to the status register, and, in later models, other special registers.
The address modes were modified by a "size" as well, permitting operations to occur on 8-bit bytes, 16-bit words, and 32-bit longs.
Most instructions are dyadic, that is, the operation has a source, and a destination, and the destination is changed. Notable instructions were:
Arithmetic: ADD, SUB, MULU (unsigned multiply). MULS (signed multiply), DIVU, DIVS, NEG (additive negation), CMP (a sort of subtract that set the status bits, but did not store the result)
Binary Coded Decimal Arithmetic: ABCD, and SBCD
Logic: EOR (exclusive or), AND, NOT (logical not)
Shifting: (logical, i.e. right shifts put zero in the most significant bit) LSL, LSR, (arithmetic shifts, i.e. sign-extend the most significant bit) ASR, ASL, (Rotates through eXtend and not:) ROXL, ROXR, ROL, ROR
Bit manipulation in memory: BSET (to 1), BCLR (to 0), and BTST (set the Zero bit).
A real weird one: TAS, test and set, performed an indivisible bus operation, permitting semaphores to work several processors shared a single bus.
Flow of control: JMP, JSR (jump to subroutine), RET (return from subroutine), RTE (return from exception, i.e. an interrupt), TRAP (a softwre interrupt), (CHK a conditional software interrupt)
Decision: Bcc a branch where the "cc" specified one of 16 tests of the condition codes in the status register: equal, greater than, less-than, carry, and most combinations and logical inversions, available form the status register.