Motorola 68000 Programming Model¶
Every classic Amiga (A500/A1000/A2000/A3000/A4000/CD32) is built around a Motorola 68000 (or later 68020/68030) CPU. Understanding the register set, memory model, status register, and instruction categories is essential for AmigaOS assembly programming, debugging Guru crashes, and interfacing C with register-based OS calls. This article is compiled from the 68000, 68010, and 68020 Primer (Kelly-Bootle & Fowler, 1985) and the 68000 Instruction Set reference appendix.
Register set¶
The 68000 has a flat, orthogonal register file — all data registers behave the same, and all address registers behave the same. This is one of the 68000's key design advantages over its 8-bit predecessors.
| Type | Count | Width | Names |
|---|---|---|---|
| Data registers | 8 | 32-bit | D0-D7 |
| Address registers | 7 | 32-bit | A0-A6 |
| Stack pointers | 2 (shared A7) | 32-bit | USP (user), SSP (supervisor) |
| Program counter | 1 | 32-bit (24 active on 68000) | PC |
| Status register | 1 | 16-bit | SR |
Data registers (D0-D7) handle all arithmetic and logical operations. Each 32-bit register can be accessed as a longword (32 bits), word (16 bits), or byte (8 bits).
Address registers (A0-A6) hold memory addresses for indirect addressing. They support only word and longword operations (no byte ops). A7 is the active stack pointer — either USP (user mode) or SSP (supervisor mode), depending on the processor state.
Data sizes¶
| Size | Bits | Range (unsigned) | Typical use |
|---|---|---|---|
| Byte | 8 | 0-255 | Characters, small values |
| Word | 16 | 0-65,535 | Addresses (short), instructions |
| Longword | 32 | 0-4,294,967,295 | Full addresses, large values |
The 68000 is big-endian: the most significant byte is at the lowest address. Words must be aligned on even (word) boundaries.
Status register (SR)¶
The 16-bit SR is divided into the system byte (bits 8-15) and the user byte / CCR (bits 0-7):
15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0
T - SS - I2 I1 I0 - | - - - X N Z V C
\_______ system byte ________/ | \________ user byte (CCR) ______/
Condition code register (CCR)¶
| Bit | Flag | Name | Meaning |
|---|---|---|---|
| 0 | C | Carry | Carry/borrow from MSB |
| 1 | V | oVerflow | Signed overflow |
| 2 | Z | Zero | Result is zero |
| 3 | N | Negative | Copy of MSB (sign bit) |
| 4 | X | eXtend | Same as C, but not always updated |
| 5-7 | - | - | Unused |
The X (extend) flag deserves attention: it is identical to C but is updated only by certain instructions. It enables multi-precision arithmetic (ADDCX, SUBCX, ROXX).
System byte¶
| Bits | Field | Meaning |
|---|---|---|
| 8-10 | I0-I2 | Interrupt mask (priority 0-7; 7 = no interrupts) |
| 13 | SS | Supervisor state (1 = supervisor, 0 = user) |
| 15 | T | Trace mode (single-step for debugging) |
The interrupt mask (I0-I2) sets the minimum interrupt priority level the CPU will service. An incoming interrupt at a level higher than the mask is serviced; lower or equal levels are ignored. Level 7 is non-maskable (NMI).
User and supervisor modes¶
The 68000 operates in one of two exclusive states:
- User mode — application programs run here. Cannot execute privileged instructions or access the supervisor stack. Any attempt triggers a privilege violation exception.
- Supervisor mode — the OS (exec.library, interrupt handlers, trap handlers) runs here. Has full access to all resources, including the system byte of the SR and the SSP.
The mode is determined by the SS flag in the SR. Mode transitions are triggered by exceptions (interrupts, traps, faults). The FC (Function Code) pins broadcast the current mode to external hardware, enabling MMU-based memory protection.
Instruction set overview¶
The 68000 has ~56 instructions, each supporting byte (.B), word (.W), or longword (.L) operands with a rich, orthogonal set of addressing modes. Key categories:
Data movement¶
| Instruction | Description |
|---|---|
MOVE |
The most-used instruction. Copies source to destination. |
MOVEA |
Move to address register (word/longword only) |
MOVEM |
Move multiple registers to/from memory (save/restore) |
MOVEP |
Move peripheral data (alternating bytes to/from memory) |
LEA |
Load effective address into An |
PEA |
Push effective address onto stack |
EXG |
Exchange two registers |
SWAP |
Swap upper and lower words of a data register |
Arithmetic¶
| Instruction | Description |
|---|---|
ADD / ADDQ / ADDI / ADDA / ADDX |
Addition (quick/immediate/address/extend) |
SUB / SUBQ / SUBI / SUBA / SUBX |
Subtraction variants |
MULU / MULS |
Unsigned / signed multiply (16x16 → 32) |
DIVU / DIVS |
Unsigned / signed divide (32/16 → 16r:16q) |
CLR |
Clear (set to zero) |
NEG / NEGX |
Negate / negate with extend |
ABS |
(68020+) Absolute value |
EXT |
Sign-extend byte→word or word→longword |
Logic and bit manipulation¶
| Instruction | Description |
|---|---|
AND / OR / EOR |
Bitwise AND, OR, XOR |
NOT |
Bitwise complement |
BCHG / BCLR / BSET / BTST |
Test/change/clear/set a single bit |
TST |
Test (set CCR based on value, no storage) |
TAS |
Test-and-set (atomic read-modify-write) |
Shifts and rotates¶
| Instruction | Description |
|---|---|
ASL / ASR |
Arithmetic shift left/right (fills with sign bit) |
LSL / LSR |
Logical shift left/right (fills with zero) |
ROL / ROR |
Rotate left/right (wraps around) |
ROXL / ROXR |
Rotate through X flag (enables multi-precision) |
Control flow¶
| Instruction | Description |
|---|---|
Bcc / BRA / BSR |
Conditional branch / branch always / branch to subroutine |
DBcc |
Decrement and branch (loop primitive) |
Scc |
Set byte to $FF (true) or $00 (false) based on condition |
JMP / JSR |
Jump / jump to subroutine (absolute address) |
RTS / RTR / RTE |
Return / return and restore CCR / return from exception |
CHK |
Check register against bound (trap if out of range) |
TRAP / TRAPV |
Software interrupt / trap on overflow |
ILLEGAL |
Generate illegal instruction exception |
BCD (Binary Coded Decimal)¶
| Instruction | Description |
|---|---|
ABCD / SBCD / NBCD |
Add/subtract/negate BCD with extend |
System control¶
| Instruction | Description |
|---|---|
RESET |
Assert reset line to external devices |
STOP |
Halt and wait for interrupt |
NOP |
No operation |
LINK / UNLK |
Link/unlink stack frame for local variables |
Condition codes for Bcc/Scc/DBcc¶
| Code | Meaning | CCR test |
|---|---|---|
EQ |
Equal | Z=1 |
NE |
Not equal | Z=0 |
CS/HS |
Carry set / unsigned higher-or-same | C=1 / C=0 |
CC/LO |
Carry clear / unsigned lower | C=0 / C=1 |
HI |
Unsigned higher | C=0 and Z=0 |
LS |
Unsigned lower or same | C=1 or Z=1 |
LT |
Signed less than | N != V |
GE |
Signed greater or equal | N == V |
GT |
Signed greater than | N == V and Z=0 |
LE |
Signed less or equal | Z=1 or N != V |
MI |
Minus (negative) | N=1 |
PL |
Plus (positive or zero) | N=0 |
F |
Never true | — |
T |
Always true | — |
Addressing modes¶
The 68000's addressing mode richness is its defining feature:
| Mode | Syntax | Description |
|---|---|---|
| Data register direct | Dn |
Operand is in register |
| Address register direct | An |
Operand is address in register |
| Address register indirect | (An) |
Pointer dereference |
| Indirect with post-increment | (An)+ |
Pop from stack / array forward |
| Indirect with pre-decrement | -(An) |
Push to stack / array backward |
| Indirect with displacement | (d,An) |
Base + offset |
| Indirect with index | (d,An,Xi) |
Base + offset + index register |
| Absolute short | (xxx).W |
16-bit address (sign-extended) |
| Absolute long | (xxx).L |
32-bit address |
| PC relative with displacement | (d,PC) |
Position-independent code |
| PC relative with index | (d,PC,Xi) |
PIC with index |
| Immediate | #xxx |
Literal value |
Post-increment (An)+ and pre-decrement -(An) modes are the foundation of stack operations and memory block transfers. MOVEM combined with -(An) pushes all registers onto the stack in one instruction.
Relevance to AmigaOS programming¶
- The 68000 register convention defines how AmigaOS library functions pass arguments: D0-D1/A0-A1 for parameters, A6 for the library base, D0 for return value.
- The supervisor/user mode split maps to exec.library internals — tasks run in user mode; interrupt handlers and exec functions run in supervisor mode.
- The CCR condition codes are tested by the
Bccfamily after every OS call to check for errors. - The MOVEM instruction is used in every interrupt handler and trap handler to save/restore registers.
- TAS is the basis for exec's
Forbid()/Permit()mutual exclusion.
See Also¶
- 68000, 68010, and 68020 Evolution
- MC68040 and MC68060 Architecture
- exec.library Reference
- SAS/C Compiler Reference
- Alerts, Gurus, and Exception Handling
- Interface Header Files
Sources: Stan Kelly-Bootle and Bob Fowler, "68000, 68010, and 68020 Primer" (Howard W. Sams, 1985), Chapters 3-6; "The 68000's Instruction Set" (instruction reference appendix); Motorola, Inc., M68000 8-/16-/32-Bit Microprocessors User's Manual, Ninth Edition (1989).
Raw: raw/hardware/68000-68010-68020-primer.md; raw/hardware/68000-instruction-set.md; raw/hardware/mc68000um.md
Updated: 2026-08-09