Skip to content

Newlib_File_IO_and_FatFs

feilipu edited this page Jul 31, 2026 · 4 revisions

Newlib File I/O and FatFs

This page expands the short File I/O summary on Home. It covers dual-stack CP/M applications, the external FatFs stack, hardware diskio backends, and install / link recipes.

Shorter entry: Disk and files. Install check (this tree, 2026-07-31): z88dk-lib +rc2014|+yaz180|+scz180|+hbios lists ff / diskio / time packages as installed. Re-run z88dk-lib +<target> on your machine before linking.

Related:

  • Platform — CPM — classic +cpm FCB file access
  • z88dk-libraries — third-party packages (ff, diskio_*, time, …)
  • In-tree notes: libsrc/_DEVELOPMENT/EXAMPLES/z80/stdio_target/readme.md (dual-stack recipes); libsrc/newlib/target/cpm/driver/file/README.md (FCB bridge)

1. Two independent stacks

API Backend Typical volume
Unprefixed open / creat / read / write / lseek / close Host filesystem of that CRT CP/M A:… via BDOS FCB when -subtype=cpm
ChaN f_* (f_mount, f_open, f_read, …) FatFs → disk_* → hardware FatFs 0:… (or other logical drives) on raw media
printf / scanf / FILE* stdio over console (and whatever open can open) BDOS CON on CPM subtypes — not FatFs unless you add a bridge

Rules of thumb:

  1. f_* is always FatFs — never “fcntl for CF/IDE/SD.”
  2. Do not rename FatFs per subtype.
  3. Bare-metal / non-CPM subtypes keep device media on f_*; unprefixed open is not “IDE open.”
  4. On -subtype=cpm, unprefixed fcntl is CP/M FCB (when the FCB bridge is linked — default for rc2014 / yaz180 / scz180 CPM CRTs).
  5. One owner of open per binary — do not mix classic +cpm fcntl objects with the newlib FCB driver in the same link.

Volumes stay independent: BDOS files and FatFs media are separate worlds unless you build a higher-level product (e.g. a CP/M-IDE firmware) that implements something else.


2. Where each path applies

Build Command shape FCB open FatFs f_*
Classic CP/M app zcc +cpm … Yes (classic) Optional third-party if you add it yourself
Newlib CP/M application zcc +rc2014|yaz180|scz180 -subtype=cpm … Yes (newlib FCB bridge) Optional via z88dk-lib
Bare / firmware ROM zcc +rc2014 -subtype=acia|sio|uart|… (etc.) No BDOS FCB Yes — primary disk API
HBIOS zcc +hbios … N/A (no subtype=cpm dual-stack) Yes — diskio_hbios + ff
Generic embedded zcc +z80 … No host FS by default Only if you supply diskio + ff

Firmware (CP/M-IDE style) vs application: firmware often runs before or as the OS image and uses FatFs (f_*, sometimes a read-only ff_ro package) for IDE/CF/SD. A .com built with -subtype=cpm is a CP/M application: BDOS console + FCB files, with optional FatFs on raw media in the same binary.


3. FatFs and hardware disk I/O

ChaN FatFs is shipped as a third-party library (not baked into every target .lib). Install with z88dk-lib. FatFs calls a small ChaN diskio API:

disk_initialize / disk_status / disk_read / disk_write / disk_ioctl

How those are provided:

Target Media diskio source FatFs package
rc2014 16-bit IDE (IDE Hard Drive Module / CF on IDE) In-tree target diskio + IDE drivers z88dk-lib +rc2014 ff (+ time for timestamps)
yaz180 8-bit CF / PPIDE-style In-tree target diskio + PPIDE z88dk-lib +yaz180 ff (+ time)
scz180 SD via Z180 CSIO Package diskio_sd z88dk-lib +scz180 diskio_sd ff time
hbios Any HBIOS logical disk Package diskio_hbios z88dk-lib +hbios diskio_hbios ff time

time supplies get_fattime helpers (time, localtime_r, system_fatfs) so write timestamps work when FatFs is not read-only.

Headers after install (examples):

#include <lib/rc2014/ff.h>
#include <lib/yaz180/ff.h>
#include <lib/scz180/ff.h>
#include <lib/scz180/diskio_sd.h>
#include <lib/hbios/ff.h>
#include <lib/hbios/diskio_hbios.h>

Libraries land under lib/clibs/{sccz80,sdcc_ix,sdcc_iy}/lib/<target>/ and are linked as -llib/<target>/<name>.


4. Install and link recipes

Requires PATH / ZCCCFG pointing at your z88dk build, and a checkout of z88dk-libraries as the working directory for z88dk-lib (or run z88dk-lib with packages available on its search path as you normally do).

4.1 FCB only (CP/M app, no FatFs)

zcc +rc2014 -subtype=cpm -clib=new app.c -o app -m
zcc +yaz180 -subtype=cpm -clib=new app.c -o app -m
zcc +scz180 -subtype=cpm -clib=new app.c -o app -m

4.2 Dual-stack (FCB + FatFs)

# RC2014 — IDE diskio already in the target library
z88dk-lib +rc2014 ff time
zcc +rc2014 -subtype=cpm -clib=new app.c \
  -llib/rc2014/ff -llib/rc2014/time -o app -m

# YAZ180 — PPIDE diskio in the target library
z88dk-lib +yaz180 ff time
zcc +yaz180 -subtype=cpm -clib=new app.c \
  -llib/yaz180/ff -llib/yaz180/time -o app -m

# SCZ180 — need package diskio_sd
z88dk-lib +scz180 diskio_sd ff time
zcc +scz180 -subtype=cpm -clib=new app.c \
  -llib/scz180/ff -llib/scz180/diskio_sd -llib/scz180/time -o app -m

Minimal dual-stack sketch:

#include <fcntl.h>
#include <unistd.h>
#include <lib/rc2014/ff.h>   /* or yaz180 / scz180 */

FATFS fs;
FIL   fil;

void demo(void)
{
    int fd = open("TEST.TXT", O_WRONLY | O_CREAT, 0);  /* BDOS A: */
    write(fd, "bdos\n", 5);
    close(fd);

    f_mount(&fs, "0:", 1);                             /* FatFs volume */
    f_open(&fil, "0:/raw.txt", FA_WRITE | FA_CREATE_ALWAYS);
    /* f_write / f_close … */
    f_unmount("0:");
}

4.3 HBIOS FatFs only (no FCB dual-stack)

z88dk-lib +hbios diskio_hbios ff time
zcc +hbios -clib=new app.c \
  -llib/hbios/ff -llib/hbios/diskio_hbios -llib/hbios/time -o app -m

4.4 List / remove packages

z88dk-lib +rc2014              # list installed third-party libs for target
z88dk-lib +scz180 -r -f ff     # remove (example)

5. CRT sizing note (CPM subtypes)

rc2014 / yaz180 / scz180 CPM CRTs allocate a larger stdio heap and open_max so static console FILEs and several dynamic FCB opens fit (stdio heap 1024, open_max 16 in current configs). Shrinking those without checking real open use will cause heap or fd-table failures.


6. What is not provided (yet)

Idea Status
open("0:/…") automatically selecting FatFs Optional future “path router” — not required for dual-stack
fopen on FatFs paths Would need a FatFs FDSTRUCT driver; prefer f_* as the primary FatFs API
Classic +cpm newlib tree migration Separate work from hardware dual-stack

7. Quick troubleshooting

Symptom Check
Undefined disk_* Link the matching diskio (-llib/…/diskio_sd or in-tree for rc2014/yaz180)
Undefined _time / _localtime_r / _system_fatfs Install and link time (-llib/…/time)
open fails / no free fds open_max and stdio heap on CPM CRT; too many static consoles + files
Two definitions of open Mixed classic fcntl objects with newlib CPM bridge
FatFs works but BDOS open does not Confirm -subtype=cpm (not bare acia/sio/uart/rom)

8. See also

Clone this wiki locally