Library — am9511 (Am9511A APU)

SkillDev tools

Am9511A (Intel 8231A) APU float library: IEEE host format vs APU format, pushf/popf status mapping, IEEE-side specials, classic/newlib link flags, multi-product rebuild. Use when editing libsrc/math/float/am9511, APU I/O, or measuring --math-am9511 / --am9511.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Library — am9511 (Am9511A APU) skill

What this skill tells your AI

The instructions your AI receives, as published by z88dk/z88dk in .agents/skills/library-am9511/SKILL.md and read by ahel’s review.

Home: libsrc/math/float/am9511/. Product docs of record: libsrc/math/float/am9511/readme.md. Vendor datasheets / app notes (canonical): external repo z88dk/techdocsamd/am9511a/ (not under this product tree).

When to load this skill

  • Editing asm/am32_*.asm, asm/z80/ or asm/8085/ push/pop/classify, or am32_fspecial.asm
  • Wiring --math-am9511 / --am9511 / classic --math-am9511_8085
  • Debugging Inf/NaN, divide-by-zero, sqrt(neg), or wrong zero after APU ops
  • Comparing am9511 vs math32 TIMER (hardware APU vs software float)

Link / flags

AudienceTypical flags
Classic z80--math-am9511 or --am9511 (alias); needs APU at the port map in config
Classic 8085--math-am9511_8085 (or target docs’ 8085 APU recipe)
Newlib--am9511 / -lam9511 with IEEE float mode as in readme
Host emulatorz88dk-ticks includes an Am9511 model (src/ticks/am9511.c); ports 0x42/0x43 default

Products (via libsrc/math/float/am9511/Makefile): am9511.lib, am9511_8085.lib, am9511_ixiy.lib, am9511_z180.lib, am9511h.lib (helper). Install into lib/clibs/ after rebuild.

Header: include/math/math_am9511.h (isinf/isnan via fpclassify).

Architecture (short)

LayerRole
Host IEEE-754 singleWhat C and the rest of z88dk use (DEHL / stack)
pushf / popfConvert IEEE ↔ Am9511 stack format; popf maps APU status → IEEE 0 / ±Inf / NaN
APU opsFADD/FSUB/FMUL/FDIV/SQRT/… on the chip (or ticks model)
am32_fspecial.asmIEEE-side specials (exp 0 / 255) before push — APU has no Inf/NaN
lam32 / c/sccz80 / c/sdccCompiler bridges and higher C functions

APU float: 24-bit mantissa, unbiased 7-bit exp (−64…+63), sign bit, normalised (or all-zero). Range about ±(2.7×10⁻²⁰ … 9.2×10¹⁸) and zero — much smaller than IEEE. Out-of-range IEEE values are clamped on push (max/zero); do not expect chip-native Inf. Chip value is mantissa × 2^exponent with 0.5 ≤ |mantissa| < 1 (binary point left of bit 23).

Host bus / I/O (datasheet interface)

All transfers are 8-bit. Host selects command vs data with C/Ḋ (plus RḊ/WṘ, CṠ). Typical programmed-I/O decode in z88dk:

AccessPort (classic default)Meaning
Data__IO_APU_DATA = base (often 0x42)Push/pop stack bytes
Status / command__IO_APU_STATUS = base+1 (0x43)Read status; write command

Byte order (critical for pushf/popf):

  • Push operand: LSB first, MSB last (4 bytes for float / 32-bit).
  • Pop result: MSB first, LSB last.
  • Wrong count or order misaligns the internal byte pointer (LIFO wrap).

Stack capacity: 8 × 16-bit or 4 × 32-bit/float entries. TOS = top, NOS = next. Binary float ops take TOS and NOS, write result to NOS, pop (stack moves up). Many derived ops (trig, log, …) also use lower stack as scratch — lower values can be destroyed (see algorithm brief / command “stack contents after” diagrams).

Command byte (single 8-bit write to status/command port):

 bit7 SVREQ(sr) | bit6–5 format | bit4–0 operation
bit6–5Format
00Floating-point 32-bit (FADD…, SQRT…)
01Fixed 32-bit (DADD…)
1xFixed 16-bit (SADD…) — bit5=1, bit6 selects single

Bit 7 = SVREQ: if set, SVREQ pin asserts when the command completes (until SVACK or a later cmd with sr=0). Library float ops normally use sr=0 (hex codes 10 FADD, 12 FMUL, 13 FDIV, 01 SQRT, …).

END pin (and SVREQ) mark completion; library float path usually polls BUSY in status instead of using END/SVREQ interrupts. Issuing a new command while busy is allowed by the bus but PAUSE stays low until the current op finishes.

APU I/O macros (config_am9511_private.inc)

Always use these (or the same ports) — do not hard-code ports in new code unless writing a multi-APU am32_stack/* clone.

MacroNormal (!__AM9511_HELPER_FUNC)Helper (__AM9511_HELPER_FUNC / am9511h)
AM9511_IN_APU_STATUSin a,(__IO_APU_STATUS)call __am9511_in_status
AM9511_IN_APU_DATAin a,(__IO_APU_DATA)call __am9511_in_data
AM9511_OUT_APU_CONTROLout (__IO_APU_STATUS),acall __am9511_out_control
AM9511_OUT_APU_DATAout (__IO_APU_DATA),acall __am9511_out_data

z80 hot push/pop often use in r,(c) / outi / out (c),… with BC = __IO_APU_DATA for speed — those paths bypass the data macros (status still uses AM9511_IN_APU_STATUS). 8085 push/pop use the macros throughout. Helper product: am9511_io.asm + -D__AM9511_HELPER_FUNC.

Status register (must know for popf)

Datasheet layout (only valid when BUSY=0; while BUSY=1 other bits are undefined — do not decode ERROR/ZERO/SIGN off a busy-rotated A):

BUSY(7) | SIGN(6) | ZERO(5) | ERROR[4:1] | CARRY(0)

ERROR is a 4-bit code, not four independent sticky bits:

Code (b4…b1)MaskMeaning
0000No error
10000x10 DIV0Divide by zero
01000x08 NEGRTSqrt/log of negative
11000x18asin/acos / eˣ domain
XX100x04 UNDFLUnderflow
XX010x02 OVRFLOverflow

Defines: libsrc/newlib/target/am9511/config_am9511_private.inc (__IO_APU_STATUS_*). Status may be read while a command runs (BUSY=1); only BUSY is meaningful then. Continuous status reads can also clear the END flip-flop — prefer one wait-for-BUSY-clear then a clean status sample.

Do not edit generated config_am9511_{private,public}.inc / .h alone. Source of truth: libsrc/newlib/target/am9511/config/config_am9511a.m4 (included from config.m4; also pulled into yaz180 libsrc/target/yaz180/config.m4). Regenerate via libsrc/newlib Makefile (make am9511 config step) or:

cd libsrc/newlib
m4 -DCFG_ASM_DEF -I../../src/m4 -I. -I.. target/am9511/config.m4 \
  > target/am9511/config_am9511_private.inc
# similarly CFG_ASM_PUB → public.inc, CFG_C_DEF → config_am9511.h
# yaz180: same flags on ../target/yaz180/config.m4 → config_yaz180_*.inc / .h

popf policy (library): re-read status after data pop; trap ZERO|ERROR before bias convert (APU zero is not a valid “normal” am9511_float for that path). OVRFL → ±Inf; UNDFL/ZERO → 0; DIV0 → ±Inf for residual chip divides; NEGRT → NaN. 0/0 → NaN and full Inf/NaN algebra for IEEE inputs are software specials, not APU encodings.

Datasheet op notes (library-relevant)

Binary float ops: TOS and NOS operands; result replaces NOS; stack pops one level. Status affected: Sign, Zero, Error field (and Carry on some fixed ops).

OpHex (sr=0)Chip cycles (typ. range)Behaviour notes
FADD0x1054–368 (24 if A=0)Exp OVR/UNDFL: mantissa “correct”, exp offset ±128
FSUB0x1170–370Same exp-offset note
FMUL0x12146–168Same
FDIV0x13154–184 (22 if divisor 0)Divisor A = TOS, dividend B = NOS. If A=0: R ← B (NOS), DIV0 set. Exp OVR/UNDFL: mantissa correct, exp ±128
SQRT0x01782–870√ of TOS → TOS; non-negative only — negative → error 0100 (NEGRT)

Derived functions (SIN/COS/…): Chebyshev approximations; many destroy lower stack slots; angles in radians. Domain errors use codes above (e.g. LN/LOG of non-positive → 0100). See algorithm brief for stack scratch diagrams.

Range-error quirk (FADD/FSUB/FMUL/FDIV): when OVRFL/UNDFL is reported, the returned exponent may be true_exp ± 128 with a usable mantissa — library popf still maps OVRFL → IEEE Inf and UNDFL → 0 rather than trusting that mantissa.

IEEE specials (software)

ModuleRole
asm/am32_fspecial.asmspec_div / spec_mul / spec_add / spec_sqrt — CF=1 if handled
asm/am32_f{div,mul,add,sub,sqrt,finv}.asmCall specials then APU path
asm/z80/am32_popf.asm, asm/8085/am32_popf.asmStatus → IEEE after op

Stack convention for binary specials: DEHL = RHS (y); stack = ret_spec, ret_user, x as L,H,E,D (IEEE host order). load_xo must preserve BC (callers stash sign in C).

Keep specials 8080-compatible in shared asm/am32_*.asm (no EXX/IX). CPU-specific I/O and push/pop stay under asm/z80/ and asm/8085/.

Force rebuild

Prefer a full product make so cimpl (ftoa/ftoe) stays in the .lib (classic %f and the math suite need them). Partial z80asm -x @am9511.lst after deleting only a few .o files is fine if other obj/<cpu>/**/*.o remain; wiping obj/ without re-running the full Makefile drops ftoa.

cd libsrc/math/float/am9511
# touch specials / popf / binary cores then full products:
rm -f obj/z80/math/float/am9511/asm/am32_fspecial.o \
      obj/z80/math/float/am9511/asm/am32_f{div,mul,add,sub,sqrt,finv}.o \
      obj/z80/math/float/am9511/asm/z80/am32_popf.o
rm -f obj/8085/math/float/am9511/asm/am32_fspecial.o \
      obj/8085/math/float/am9511/asm/8085/am32_popf.o
make
cp -f ../../../am9511.lib ../../../am9511_8085.lib ../../../lib/clibs/

After install, delete suite .bin/.map before remeasure.

Prove link: z88dk-z80nm lib/clibs/am9511.lib | rg 'spec_|popf|fdiv|ftoa'.

Measure / suite

  • Suite: test/suites/mathtest_am9511.bin, test_am9511_8085.bin with -DMATH_SPECIALS (finite + Inf/NaN algebra via am32_fspecial + popf).
  • Do not add bare -lm/-lgenmath ahead of --math-am9511: genmath’s sqrt can win the link and bypass the APU path.
  • TIMER benches: classic recipes with --math-am9511 / --math-am9511_8085; see am9511/readme.md and methodology-measure.
  • Ticks APU: src/ticks/am9511.c (approximate model — not bit-exact silicon). Status-bit accuracy is a separate work item if suite/hardware disagree.

Further reading (techdocs)

Canonical tree: https://github.com/z88dk/techdocs/tree/master/amd/am9511a (Do not treat a local PDF copy in a product working tree as the cite target.)

FileUse for
Am9511 Arithmetic Processor.pdfPrimary: interface (C/Ḋ, push/pop byte order), status, command format, FADD/FDIV/SQRT descriptions, float format, cycle table
Am9511A-9512FP_Processor_Manual.pdfFuller processor / 9512 companion material
Am9511_Algorithm_Details.pdfAccuracies, stack scratch per op, ranges beyond the short datasheet
An Efficient Software Driver for Am9511A.pdfHost driver / sequencing patterns
HARWELL - Using the Am9511A.pdfApplication / systems notes

In-tree companion: libsrc/math/float/am9511/readme.md (layout, API, benches). YAZ180 interrupt/FIFO driver (not the same as classic pushf/popf path): libsrc/target/yaz180/device/am9511a/readme.md.

Related skills

  • Soft IEEE float: library-math32, library-math16
  • Measure / suite / ticks: methodology-measure, tool-ticks
  • 8085 stack-only library rules: cpu-8085
  • Classic vs newlib product shape: library-classic, library-newlib

Signals

GitHub stars
1k
Forks
206
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
library-am9511
Source
github.com/z88dk/z88dk