13 KiB
68040.library and 68060.library — CPU Support Libraries
Overview
The 68040 and 68060 processors removed certain instructions that the 68020/68030 and 68881/68882 FPU supported in hardware. These "unimplemented" instructions cause a Line-F exception (vector $2C) when executed. The 68040.library and 68060.library are trap handler libraries that catch these exceptions and emulate the missing instructions in software, providing transparent backward compatibility.
Why Were Instructions Removed?
Motorola's 68040 design made a strategic tradeoff: fit MMU, FPU, and dual caches onto a single die while reaching competitive clock speeds — all within a ~1.2 million transistor budget. To achieve this, two painful decisions were made:
-
Drop microcode-heavy FPU instructions. Trigonometric (
FSIN,FCOS), logarithmic (FLOG2,FLOGN), and exponential (FETOX,FTWOTOX) functions require ROM lookup tables and iterative algorithms in microcode, consuming thousands of transistors. Sacrificing them freed silicon for the on-chip 4 KB data + 4 KB instruction caches — a much larger performance win for typical integer-heavy Amiga software. -
Eliminate the barrel shifter. The dedicated barrel shifter circuit was removed, simplifying the critical timing path and allowing higher clock speeds. This is why certain integer instructions (
MOVEP) were also dropped.
The 68060 doubled down: additional integer instructions (MOVEP, CMP2, CAS2, CHK2) were removed to make the instruction decoder leaner, enabling superscalar execution (up to two instructions per clock in the best case).
The Tradeoff: Pros and Cons
| Pro | Con |
|---|---|
| Smaller die → lower cost, higher yield | Programs crash without the trap library |
| Fewer transistors → less heat, lower power | Trap overhead: ~30–200 cycles per emulated instruction (vs ~15–80 if native) |
| Cleaner critical paths → higher MHz | 68040.library (~24 KB) + 68060.library (~40 KB) must ship separately |
| Freed silicon enabled on-chip MMU + larger caches | Some instructions (FSINCOS) have no software workaround |
| Fewer microcode bugs (68881/68882 errata avoided) | Timing unpredictability — trap latency varies by instruction |
Bottom line: Motorola bet that most applications lean on integer math (games, productivity, OS), where the larger caches and higher clocks delivered a clear win, while the small fraction of transcendental-heavy code could tolerate software emulation. For the Amiga ecosystem this was a good bet — every accelerator card shipped with SetPatch and the 68040.library on its install disk, making compatibility a one-time setup concern.
Without these libraries, any program using the affected instructions would crash with a Line-F exception on 040/060 hardware.
What Instructions Are Emulated?
68040.library
The 68040 removed several FPU instructions that the 68881/68882 supported:
| Category | Missing Instructions | Description |
|---|---|---|
| Transcendental FPU | FSIN, FCOS, FTAN, FASIN, FACOS, FATAN |
Trig functions |
| Transcendental FPU | FSINH, FCOSH, FTANH, FATANH |
Hyperbolic functions |
| Transcendental FPU | FLOG2, FLOG10, FLOGN, FLOGNP1 |
Logarithms |
| Transcendental FPU | FETOX, FETOXM1, FTWOTOX, FTENTOX |
Exponentials |
| Other FPU | FMOD, FREM |
Modulo/remainder |
| Other FPU | FGETEXP, FGETMAN |
Get exponent/mantissa |
| Other FPU | FSGLDIV, FSGLMUL |
Single-precision ops |
| Integer | MOVEP |
Move peripheral (not on all 040 revisions) |
68060.library
The 68060 removed everything the 040 removed plus additional instructions:
| Category | Additionally Missing | Description |
|---|---|---|
| Integer | MOVEP |
Move peripheral (byte-strided) |
| Integer | CAS2 |
Compare-and-swap dual |
| Integer | CHK2, CMP2 |
Range check |
| Integer | MULU.L (64-bit) |
64-bit unsigned multiply |
| Integer | MULS.L (64-bit) |
64-bit signed multiply |
| Integer | DIVU.L (64-bit) |
64-bit unsigned divide |
| Integer | DIVS.L (64-bit) |
64-bit signed divide |
| FPU | All 68040-missing FPU ops | Same as above |
| FPU | FMOVECR |
Move constant ROM |
| FPU | FDABS, FDSQRT, etc. |
Some double-precision ops |
How They Work
1. Program executes FSIN (opcode $F200 xxxx)
2. 68040/060 CPU has no microcode for this → Line-F exception (#11)
3. CPU vectors to the Line-F exception handler
4. 68040.library's handler decodes the opcode from the stack frame
5. Software emulates FSIN using basic FADD/FMUL/FDIV
6. Result is placed in the correct FPU register
7. Handler returns → program continues as if nothing happened
graph TB
APP["Application code"] -->|executes FSIN| CPU["68040/060 CPU"]
CPU -->|"opcode not in microcode"| EXC["Line-F Exception #11"]
EXC --> VEC["Exception vector table"]
VEC --> LIB["68040.library trap handler"]
LIB --> DEC["Decode opcode from stack frame"]
DEC --> EMU["Software emulation<br/>(FADD/FMUL/FDIV series)"]
EMU --> RES["Place result in FPU register"]
RES --> RET["RTE — return to application"]
RET --> APP
style CPU fill:#e8f4fd,stroke:#2196f3
style LIB fill:#fff9c4,stroke:#f9a825
style EMU fill:#ffe0b2,stroke:#ff9800
Installation
These libraries are loaded at boot time as resident modules. They install themselves as the Line-F exception vector handler.
; In startup-sequence or user-startup:
LIBS:68040.library ; for 68040 systems
; or:
LIBS:68060.library ; for 68060 systems (replaces 68040.library)
The library is typically loaded by SetPatch or an explicit C:LoadModule:
C:LoadModule LIBS:68040.library
; or for 68060:
C:LoadModule LIBS:68060.library
struct (ROM Tag)
Both libraries register as RTF_COLDSTART resident modules with high priority to ensure they are initialized before any user code runs:
/* Typical RomTag for 68040.library: */
static struct Resident romtag = {
RTC_MATCHWORD, /* $4AFC */
&romtag,
&endskip,
RTF_COLDSTART, /* flags: cold start */
40, /* version */
NT_LIBRARY,
105, /* priority: very high */
"68040.library",
"68040.library 40.1 (1.1.93)\r\n",
initRoutine
};
Detection
/* Check which CPU is present: */
if (SysBase->AttnFlags & AFF_68040) /* 68040 */
if (SysBase->AttnFlags & AFF_68060) /* 68060 */
/* AttnFlags bits: */
#define AFB_68010 0
#define AFB_68020 1
#define AFB_68030 2
#define AFB_68040 3
#define AFB_68060 7 /* added by 68060.library */
#define AFB_68881 4 /* FPU present */
#define AFB_68882 5
#define AFB_FPU40 6 /* 040 internal FPU */
Performance Impact
Software emulation of transcendental FPU instructions is 10–100x slower than the 68881/68882 hardware implementation. Performance-critical code should:
- Use lookup tables for trig functions
- Use polynomial approximations (Chebyshev, CORDIC)
- Avoid
FSIN/FCOSin tight loops
Common Sources
| Library | Source |
|---|---|
| 68040.library 37.4 | Commodore (OS 3.0 distribution) |
| 68040.library 40.1 | Commodore (OS 3.1 distribution) |
| 68060.library 40.1 | Phase5 (original 68060 accelerators) |
| 68060.library 46.x | Motorola reference implementation |
When to Use / When NOT to Use
| Scenario | Use Library? | Why |
|---|---|---|
| Running FPU-heavy code compiled for 68881/68882 on 040 | Yes | Missing transcendental instructions will crash |
| Running FPU-heavy code compiled for 68881/68882 on 060 | Yes | 68060.library replaces 68040.library; covers more missing ops |
| Your code only uses basic FPU (FADD/FMUL/FDIV) | No | These are native on 040/060 — no library needed |
| Your code uses MOVEP on 040 (some revisions) | Yes | Some 040 masks lack MOVEP microcode |
| Code uses CAS2 or CHK2 on 060 | Yes | 68060 removed these integer ops |
| Published application targeting 68000–060 | Yes | Ship both libraries as dependencies |
| Benchmarking FPU performance | No | Emulation skews results; use native ops only |
Named Antipatterns
1. "The Missing Library" — No 68040.library on 040
Symptom: Program works on 68030, crashes with Line-F exception on 68040.
Why it fails: The software used FSIN (or another removed instruction) from a 68881 FPU library compiled for 68030. The 68040 has no microcode for it, and without the trap library, the exception is unhandled.
Fix: Always install 68040.library on 040 systems and 68060.library on 060 systems. SetPatch typically does this, but verify it loaded.
2. "The Trig Loop" — FSIN/FCOS in Inner Loops on 040
Symptom: Acceptable performance on 68030+68881, but drops to single-digit FPS on 68040.
/* BROKEN — software-emulated FSIN on every frame */
for (int i = 0; i < count; i++) {
float angle = i * step;
points[i].x = sin(angle); /* calls FSIN via library emulation */
}
Fix: Precompute a lookup table, or use a polynomial approximation that only needs FADD/FMUL:
/* CORRECT — lookup table: no FSIN at runtime */
float sin_table[360];
for (int i = 0; i < 360; i++)
sin_table[i] = sin(i * M_PI / 180.0); /* done once at startup */
3. "The Wrong CPU Check" — Testing AFF_68040 on 68060
Symptom: Code detects CPU as 68040 when running on 68060, then loads wrong library.
/* BROKEN — 68060 matches AFF_68040 check */
if (SysBase->AttnFlags & AFF_68040)
LoadModule("LIBS:68040.library"); /* wrong library on 060! */
Fix: Check 68060 first — it's a superset:
/* CORRECT — check most specific first */
if (SysBase->AttnFlags & AFF_68060)
LoadModule("LIBS:68060.library");
else if (SysBase->AttnFlags & AFF_68040)
LoadModule("LIBS:68040.library");
Pitfalls
1. 68060.library Without First Installing 68040.library
Some setups load 68060.library directly without also installing 68040.library. The 68060 library is a replacement for the 68040 library (it includes all 040 emulation plus 060-specific additions), but boot scripts that check-for-library-before-loading can fail if both aren't present.
; WRONG — 68040.library may be needed by other components
C:LoadModule LIBS:68060.library
; CORRECT — install both or let 68060 supersede
C:LoadModule LIBS:68040.library LIBS:68060.library
; 68060.library patches over 68040.library's functions
2. Forgetting Library on Emulated 68040/060
On UAE or MiSTer with 68040/060 emulation enabled, the same Line-F exceptions occur. The emulated CPU has the same missing instructions as real silicon. Always include the libraries in your emulated Workbench setup.
Impact on FPGA/Emulation — MiSTer & UAE
TG68K Core
The Minimig-AGA core on MiSTer uses the TG68K CPU core, which implements 68020 only. It does not implement the 68040 or 68060 instruction sets, so 68040.library and 68060.library are not needed on MiSTer's Minimig core.
UAE Emulation
WinUAE and FS-UAE can emulate 68040 and 68060 CPUs. When these are enabled:
- The emulator's CPU correctly triggers Line-F exceptions for removed instructions
- The same trap libraries must be installed in the emulated Amiga's
LIBS:directory - Omitting them produces the same crashes as real hardware
M68040 / M68060 FPGA Cores
If building a custom FPGA core with a 68040 or 68060 implementation (e.g., the m68040 project in this workspace), the core must:
- Raise a Line-F exception for unimplemented opcodes
- Provide a valid exception stack frame so the library can decode the opcode
- Not silently execute removed instructions (producing wrong results with no error)
Modern Analogies
| Amiga Concept | Modern Equivalent | Why It's the Same Pattern |
|---|---|---|
| 68040.library emulating FSIN | CPU microcode patches (Intel/AMD Spectre/Meltdown mitigations) | Hardware defect or missing feature patched by software at exception time |
| 68060.library superseding 68040.library | ARM exception levels with nested handlers | More-capable handler replaces less-capable one at same exception vector |
Library auto-detection via AttnFlags |
CPUID instruction + feature flag checking | Runtime query determines which code path to use |
| Trap-and-emulate for missing ops | Rosetta 2 (x86 → ARM translation) | Transparent instruction emulation invisible to application |
FAQ
Does 68060.library replace 68040.library entirely?
Yes. 68060.library contains all 68040.library emulation plus additional routines for instructions the 68060 removed beyond what the 040 removed (CAS2, CHK2, 64-bit MUL/DIV, etc.). It patches the same exception vector and supersedes the 040 library.
Can I use FSIN in code shipped to 68040 customers?
Yes, but you must document that 68040.library is required. The library will emulate FSIN transparently. However, be aware that emulated FSIN is 10–100x slower than native 68881 FSIN — avoid it in performance-critical paths.
Does the library handle MOVE16 on 68040?
No. MOVE16 is a native 68040 instruction — it is not emulated by the library. The confusion arises because MOVEP (a different instruction, byte-strided) IS emulated on 68040 revisions without microcode for it.
References
- Motorola: MC68040 User's Manual — unimplemented instruction list
- Motorola: MC68060 User's Manual — unimplemented instruction list
- NDK39:
exec/execbase.h—AttnFlags - Phase5: 68060.library source (public domain)