{"id":35132975,"url":"https://github.com/dbalsom/fluxfox","last_synced_at":"2026-03-27T04:08:25.178Z","repository":{"id":213983937,"uuid":"735411780","full_name":"dbalsom/fluxfox","owner":"dbalsom","description":"A floppy disk image library in Rust","archived":false,"fork":false,"pushed_at":"2025-12-28T02:50:12.000Z","size":45243,"stargazers_count":130,"open_issues_count":8,"forks_count":7,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-12-30T01:43:43.723Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dbalsom.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-24T20:40:05.000Z","updated_at":"2025-12-28T21:17:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"0b0dcc85-c65b-400e-a59c-8ab1b8da4c7e","html_url":"https://github.com/dbalsom/fluxfox","commit_stats":null,"previous_names":["dbalsom/fluxfox"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/dbalsom/fluxfox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbalsom%2Ffluxfox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbalsom%2Ffluxfox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbalsom%2Ffluxfox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbalsom%2Ffluxfox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dbalsom","download_url":"https://codeload.github.com/dbalsom/fluxfox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbalsom%2Ffluxfox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31018555,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T03:51:26.850Z","status":"ssl_error","status_checked_at":"2026-03-27T03:51:09.693Z","response_time":164,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-28T07:05:43.409Z","updated_at":"2026-03-27T04:08:25.157Z","avatar_url":"https://github.com/dbalsom.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![image](doc/img/fluxfox_logo.png)\n\n# fluxfox\n\nA floppy disk image library in [Rust](https://www.rust-lang.org/)\n\n[![Crate Badge]][Crate] [![Docs Badge]][Docs] [![Deps.rs Badge]][Deps.rs] [![License Badge]](./LICENSE)\n\n## Try fluxfox in your [web browser](https://dbalsom.github.io/fluxfox/index.html)!\n\n[![Github Pages](https://github.com/dbalsom/fluxfox/actions/workflows/deploy_ff_egui_app.yml/badge.svg)](https://github.com/dbalsom/fluxfox/actions/workflows/deploy_ff_egui_app.yml)\n\n**This library is under heavy initial development. The API in this repository is subject to change at any time.**\n\n![image](doc/img/visualization_example.png)\n\u003cp align=\"center\"\u003eArac (1988, Digital Leisure Corporation) showing the signature of MINDER copy protection\u003c/p\u003e\n\n## Goals\n\n* fluxfox is intended to serve the needs of an emulator that wishes to read various disk image formats. Its primary\n  focus has been the PC platform, but has recently gained initial support for other platforms such as the Amiga,\n  Macintosh, and Atari ST.\n\n  It provides an interface by which an emulator can load a disk image, then perform operations on the disk image\n  consistent with typical operations supported by a common PC floppy disk controller such as the NEC μPD765A.\n\n  Low level access to the track bitstream is also available for implementing other controller types.\n\n### Non-Goals\n\n* fluxfox is not intended to be a general purpose disk image conversion library, although it can write to a few\n  supported formats.\n  There are other tools, (libdisk, SAMdisk, Applesauce, HxC, pri/pfi/psi) which are more appropriate for that purpose.\n\n## Disk Image Support\n\nThere are a dizzying array of floppy disk image formats - formats often arise to meet the specific needs of\ncertain hardware platforms and the disk controllers and software protection methods that were common to such\nplatforms. At least initially, this library will focus on disk image formats that are commonly associated with the\nIBM PC platform.\n\nAt least partial support for the following disk images is under development:\n\n### Raw Sector Images\n\n* **Raw Sector Image** (IMG, IMA, DSK, ADF, ST, etc.)\n    * Raw sector images are ubiquitous, easily the most common type of disk image used with PC emulators. These files\n      simply contain raw sectors in order, which are all assumed to be exactly 512 bytes. No header is present, but the\n      layout of the disk can generally be determined by the file size.\n    * The obvious limitation of this format is that any non-standard disk layout cannot be represented. However, these\n      images are very convenient and simple if working with non-copy-protected images.\n    * Fluxfox converts raw sector images into Bitstream images on load.\n\n### Sector-based Disk Images\n\nSector-based images encode byte data for each sector, typically with metadata about the sector's id markers and CRC\nstatus.\nThese images can support many copy-protected titles, but may fail to encode more advanced protections, sometimes produce\nimpossible track encodings, and are not ideal for archival purposes or research. Due to limitations of these formats,\nfluxfox treats them as a special `MetaSector` track type.\n\n* **Teledisk** (TD0)\n    * A disk image format used by Sydex TELEDISK, an early commercial disk-copying program.\n    * No official documentation exists, however Dave Dunfield published notes on the disk format and the format is\n      supported by a number of tools and emulators.\n    * Multiple versions exist, including different compression algorithms. Version 2 Teledisk images may be compressed\n      with LZHUF compression. Version 1.x images may use a custom LZW implementation instead. Both versions are\n      supported\n      thanks to [retrocompressor](https://github.com/dfgordon/retrocompressor)\n      by [dfgordon](https://github.com/dfgordon).\n* **ImageDisk** (IMD)\n    * ImageDisk is a format developed by Dave Dunfield as an open alternative to TeleDisk format images, although it\n      has some encoding limitations.\n* **PCE Sector Image** (PSI)\n    * One of several image formats developed by Hampa Hug for use with his emulator,  [PCE](http://www.hampa.ch/pce/).\n      A flexible format based on RIFF-like data chunks. Perhaps the most advanced of all sector-based disk images, it\n      has been used to encode a variety of copy-protected titles.\n\n### Bitstream Disk Images\n\nBitstream images store the low-level FM or MFM encoded bit stream of each track on a diskette. These images typically\ncan encode most protection types seen on the PC, given the appropriate metadata (weak and damaged bits), but are more\ncomplex than sector images to manipulate and write back to.\n\n* **PCE Raw Image** (PRI)\n    * One of several image formats developed by Hampa Hug for use with his emulator, [PCE](http://www.hampa.ch/pce/).\n      Along with track bitstream data, PRI supports weak bit masks.\n* **MFM Bitstream Image** (MFM)\n    * A bitstream format created for use with the HxC drive emulation software.\n    * Only MFM-encoded track data is included. There is no support for weak bits or other metadata.\n* **HFE Bitstream Image** (HFE)\n    * Another format associated with the HxC software, HFE is also a bitstream container, however unlike MFM it supports\n      multiple encoding types. There are several versions of HFE supported by HxC, HFEv3 being the newest, however the\n      format is still considered experimental and not finalized. fluxfox supports HFE v1 files.\n* **86Box Floppy Image** (86F)\n    * A format designed around the internal representation of disks in the 86Box emulator. Bitstream based and flexible\n      in terms of per-track parameters, it also allows exact encoding of bitcell length to support track wrapping.\n* **Interchangeable Preservation Format** (IPF)\n    * A format developed by the [Software Preservation Society](http://www.softpres.org/), originally designed to hold\n      Amiga disk images, but expanded to Atari ST and theoretically capable of holding a variety of disk image types.\n    * IPF files, unlike other bitstream-level images, divide a disk into elements which must be reconstructed to\n      reproduce the original track data.\n    * The SPS has curated official IPF disk image collections, although unofficial tools exist to create IPF files.\n      These\n      tools do not always create valid IPF images or properly set IPF metadata. Fluxfox will reject such images.\n\nSome Bitstream-level formats, such as MFM and HFE, do not support specifying an absolute bit length. This can cause\nproblems when emulating certain copy-protection schemes that involve precise handling of reading across the index\n(track wrapping).\n\n### Flux-Based Disk Images\n\nThese images are created with specialized hardware that records the raw flux transitions reported by a disk drive. This\nis the lowest possible level of disk image, and is ideal for archival purposes.\n\nFlux images can be divided into two basic types, solved and unsolved flux.\n\nUnsolved flux images are the most difficult of the three types of format to read and manipulate. Generally a lengthy\nconversion process is required to analyze and combine the 3-5 revolutions of each track that is typically captured with\na flux capture device. This makes them less than ideal for the purposes of emulation. Unsolved images cannot really be\nwritten to in a sensible way - nor should you want to.\n\nSolved flux images represent a post-processed flux capture where multiple revolutions have already been analyzed and\ncombined. The resulting flux stream should represent a correct, clean read of each track. Metadata may need to be\nprovided along with solved flux images as detection of weak bits, etc., is only possible by comparing multiple\nrevolutions which are no longer present in a solved image. Solved flux images can technically be written to - but doing\nso is a complicated process.\n\n### Raw Flux Images\n\n* **PCE Flux Image** (PFI)\n    * One of several image formats developed by Hampa Hug for use with his emulator, [PCE](http://www.hampa.ch/pce/).\n      Contains raw flux stream data, for an arbitrary number of revolutions. Similar to Kryoflux, but in a single-file\n      container.\n\n* **SuperCardPro Image** (SCP)\n    * A format designed for the [SuperCardPro](https://www.cbmstuff.com/index.php?route=product/product\u0026product_id=52)\n      flux imaging hardware, this format has become quite popular as a single-file flux container. The format supports\n      several potentially useful metadata fields, but they are so frequently set to garbage values in SCP images in the\n      wild that is impossible to trust them.\n    * SCP images can also contain resolved flux tracks, if desired. Some emulators can write back to SCP, but write a\n      single revolution.\n\n* **KryoFlux Stream Files** (RAW)\n    * Less of an image format, and more of a collection of stream protocol dumps produced by\n      the [Kryoflux](https://kryoflux.com/) flux imaging hardware. These 'images' comprise a set of files with the\n      `.raw` extension, one file per track.\n    * Each track file may contain an arbitrary number of revolutions.\n\n### Resolved Flux Images\n\n* **MAME Flux Image** (MFI)\n    * A resolved flux format designed for the famous MAME emulator (which emulates many kinds of computer, not just\n      arcade machines.)\n    * MFI images contain a single revolution, encoding \"zones\" of NFA's or surface damage to support various\n      copy-protection methods.\n\n### Hybrid / Multi-Resolution Images\n\nSome disk image formats support both bitstream and flux-level track representation.\n\n* **Applesauce MOOF** (MOOF)\n    * A modern, chunked disk image format intended to store disk images for the Apple Macintosh. It can store either\n      MFM or GCR encoded tracks at either bitstream or resolved flux resolution.\n\n### Disk Encodings\n\n* **MFM**\n    * Most floppy images used on the IBM PC\n      primarily use [MFM](https://en.wikipedia.org/wiki/Modified_frequency_modulation) encoding. These disks are\n      commonly referred to as 'double density'.\n* **FM**\n    * Earlier 8-inch floppies used FM encoding instead and were referred to as 'standard density'.\n    * Commercial disk duplicators would sometimes include an FM-encoded track at the end of an otherwise MFM-encoded\n      diskette, containing duplication info. Sometimes these \"duplication marks\" contain useful clues as to the type\n      of copy-protection used.\n* **GCR**\n    * [Group Coded Recording](https://en.wikipedia.org/wiki/Group_coded_recording) is an encoding scheme that is more\n      complex but also more efficient than either FM or MFM. It appears in several variants, 4:4, 5:3, and 6:2 being a\n      few.\n\n      Fluxfox supports loading and categorizing GCR-encoded tracks, but does not currently support decoding them.\n\n## Track Schemas\n\nFluxfox describes the layout of a track using a Track \"Schema\", allowing it to eventually support a variety of hardware\nplatforms.\n\nCurrently, two track schema types are defined:\n\n* **System 34** - This is the original IBM PC track format, including its ISO variant that omitted IAM markers.\n* **Amiga `trackdisk`** - This is the traditional layout of an Amiga floppy, typically read and written to an entire\n  track at a time. Note that many copy-protected Amiga titles used custom track formats, and these are not attempted\n  to be detected or decoded.\n\nFluxfox can handle multiple track schemas per disk, making it possible to load double and triple-format diskettes.\n\n## Filesystem Support\n\nfluxfox can mount FAT12 filesystems stored on floppy disk images,\nusing [rust-fatfs](https://github.com/rafalh/rust-fatfs).\nI have forked this library to provide custom support for more nonconforming disk images.\n\nFAT12 support enables reading the filesystem of PC and Atari ST format diskettes.\n\nWith fluxfox's `zip` feature enabled, disk images can be created from loose files contained a ZIP file.\n\n### Current limitations\n\n- 160k/180k disk images that predate the DOS 2.0 Bios Parameter Block cannot currently be mounted.\n\n## Logging\n\nfluxfox uses [env_logger](https://crates.io/crates/env_logger) for logging output. If your application also uses\nenv_logger, you will see fluxfox's messages along with your own. If fluxfox's output is too noisy,\nyou can add `fluxfox=error` to your `RUST_LOG` environment variable to limit output to only critical error messages.\n\n## GUI\n\n![image](doc/img/fluxfox_egui_01.png)\n\nI'm building a GUI for fluxfox powered by [egui](https://github.com/emilk/egui) to demonstrate fluxfox's capabilities,\nand provide functionality that will eventually be incorporated into the [MartyPC](https://github.com/dbalsom/martypc)\nemulator.\nIt can be built as a native application or wasm - you can try it in your web\nbrowser [here](https://dbalsom.github.io/fluxfox/index.html).\n\nIt is an easy way to use fluxfox's visualization feature - just drag and drop an image.\n\nThe GUI is still a work in progress, but already has several interesting features. You can read more about\nit [here](https://github.com/dbalsom/fluxfox/tree/main/crates/ff_egui_app).\n\n## TUI\n\n![image](doc/img/ffedit_01.png)\n\nI started work on a basic disk editor with a TUI powered by [ratatui](https://ratatui.rs/), but most of my work is\nnow focused around the GUI. It may still be useful as a proof of concept if someone is interested in developing it\nfurther.\n\n## CLI\n\nAlso a work in progress - a CLI interface to various fluxfox features. It is\navailable [here](https://github.com/dbalsom/fluxfox/tree/main/crates/fftool).\nLike the TUI, it is on the back burner while I build out the GUI.\n\n## Visualization\n\nfluxfox can produce a graphical visualization of a disk image if the image is of bitstream resolution or higher.\n\nVisualization requires the `viz` feature to be specified.\n\nAn included example, `imgviz`, is a command-line utility that can produce a visualization and save it to PNG.\n\nThe following command will run `imgviz` and produce a 1024x1024 (or 2048x1024) resolution visualization with 4x\nsupersampling named `output.png`:\n\n```\ncargo run -r -p imgviz -- -i \"input.pri\" -o=\"output.png\" --angle=2.88 --hole_ratio=0.66 --index_hole --data --metadata --decode --resolution=2048 --ss=4 \n```\n\n* The `angle` parameter determines the angle of the index mark on the unit circle for head #0. An angle of 0 is default\n  and will place the index mark on the right side (the 3 o'clock position, similar to HxC)\n* The `hole_ratio` parameter determines the relative size of the inner radius to the outer radius. A ratio of 0.66 is\n  approximately accurate for a 5.25\" diskette, mapping to 22mm of servo travel. You may prefer to reduce this factor for\n  visualization purposes.\n* `index_hole` will render a circle representing the position of the index hole on the diskette.\n* `data` will render the data contained in the disk image, either as MFM-encoded or decoded stream, depending on whether\n  `decode` is specified.\n* `metadata` will overlay colored regions representing sector headers and sector data.\n    * Either `data` or `metadata` must be supplied, or no image will be drawn!\n* `decode` will decode the MFM-encoded data, showing a representation of the actual data on disk (usually more visually\n  interesting)\n* `resolution` determines the final output height of the resulting image. If an image is two-sided, it may be double\n  this width or more.\n* `ss` specifies a supersampling factor. The image will be rendered at this multiple of the specified `resolution` and\n  down-sampled using the [fast_image_resize](https://github.com/Cykooz/fast_image_resize) crate.\n* `errors` will render any decoding errors as the final layer on top of the visualization. This is useful for seeing the\n  quality of the resolved image, spotting weak bits, etc.\n\nBe sure to provide the `-r` parameter to cargo run, to run imgviz in release mode. Debug mode will be very slow and use\na lot more memory!\n\nThe image will be square with a single disk surface if the image is single-sided. Otherwise, both sides of the disk will\nbe rendered side by side.\n\nWhen working with Kryoflux file sets, any file in a set may be used as an input filename.\n\nRun with the `-h` parameter to see more command-line options.\n\nAn example visualization is shown at the top of this README.\n\n## Links\n\nfluxfox and its various utilities are powered by:\n\n- [egui](https://github.com/emilk/egui) by Emil Ernerfeldt\n- [binrw](https://github.com/jam1garner/binrw) by jam1garner\n- [fast_image_resize](https://github.com/Cykooz/fast_image_resize) by Kirill Kuzminykh\n- [rust-fatfs](https://github.com/rafalh/rust-fatfs) by Rafał Harabień\n- [retrocompressor](https://github.com/dfgordon/retrocompressor) by Daniel Gordon\n- [tiny_skia](https://github.com/linebender/tiny-skia) by Yevhenii Reizner\n- [ratatui](https://ratatui.rs/)\n\n[Crate]: https://crates.io/crates/fluxfox\n\n[Crate Badge]: https://img.shields.io/crates/v/fluxfox?logo=rust\u0026style=flat-square\u0026logoColor=E05D44\u0026color=E05D44\n\n[License Badge]: https://img.shields.io/crates/l/fluxfox?style=flat-square\u0026color=1370D3\n\n[Docs]: https://docs.rs/fluxfox\n\n[Docs Badge]: https://img.shields.io/docsrs/fluxfox?logo=rust\u0026style=flat-square\u0026logoColor=E05D44\n\n[Deps.rs]: https://deps.rs/repo/github/dbalsom/fluxfox\n\n[Deps.rs Badge]: https://deps.rs/repo/github/dbalsom/fluxfox/status.svg?style=flat-square\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbalsom%2Ffluxfox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdbalsom%2Ffluxfox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbalsom%2Ffluxfox/lists"}