Skip to main content

diskii - Apple II Disk Image Tool & Library

Project description

diskii - Apple II Disk Image Tool & Library

builds.sr.ht status

diskii is both a command-line utility and Python library for reading, writing, and manipulating Apple II disk images. It supports both DOS 3.3 and ProDOS filesystems across various image formats.

Features

Disk Image Reading

  • Complete DOS 3.3 support: Read catalogs, extract files, handle all file types (T/I/A/B/S/R)
  • Full ProDOS support: Volume directories, subdirectories, all storage types (seedling/sapling/tree)
  • DOS 3.2 support: Read 13-sector disk images (.d13 format)
  • Multiple image formats: .dsk, .do, .po, .hdv, .d13
  • Automatic format detection: Smart detection based on file extension and content analysis

File Operations

  • File extraction: Read any file from disk images to host filesystem
  • File writing: Create new files on disk images with proper metadata
  • File type preservation: Maintain Apple II file types and auxiliary information
  • Cross-format operations: Copy files between DOS 3.3 and ProDOS images

Disk Image Creation

  • Blank disk creation: Create empty DOS 3.3, DOS 3.2, and ProDOS images
  • Multiple sizes supported: Standard 140K disks up to 32MB ProDOS volumes
  • Proper filesystem initialization: Correct VTOC, catalogs, and volume bitmaps

Advanced Features

  • Batch operations: Process multiple disk images in one command
  • Hierarchical directory support: Full ProDOS subdirectory navigation
  • Sparse file handling: Efficient handling of ProDOS sparse files
  • Free space tracking: Volume bitmap and VTOC management
  • BASIC (de)tokenization: Convert between tokenized and text BASIC programs with 100% Apple II ROM compliance
  • BASIC syntax validation: ROM-compliant syntax checking for Apple II BASIC programs
  • ProDOS corruption protection: Graceful handling of malformed directory entries
  • DOS file size accuracy: Respects Apple II directory size fields vs sector padding
  • Robust error handling: Comprehensive error detection and graceful degradation
  • Type-safe: Full type annotations throughout
  • Comprehensive testing: 1100+ tests with 100% pass rate, fuzzing coverage, and compatibility validation

Installation

pip install diskii

Or with Poetry:

poetry add diskii

Command Line Usage

diskii provides a comprehensive command-line interface for disk image manipulation:

# Show disk information
diskii info mydisk.dsk
diskii info *.dsk --summary              # Show summary for multiple disks

# Extract files from disk images  
diskii extract mydisk.po                 # Extract all files from one disk
diskii extract *.dsk --output extracted/ # Extract from multiple disks
diskii extract mydisk.dsk --files HELLO.BAS  # Extract specific files

# Add files to a disk
diskii add mydisk.po myfile.txt *.bas    # Add multiple files

# Create blank disk images
diskii create blank.po --name MYDISK

# Reorder sectors between different orderings
diskii reorder mydisk.dsk output.po

# BASIC program utilities
diskii basic detokenize HELLO.BAS
diskii basic tokenize myprogram.txt --variant applesoft
diskii basic validate myprogram.txt

For detailed help on any command:

diskii --help
diskii <command> --help

Python Library Usage

import diskii

# Open any disk image - format detected automatically
with diskii.open_disk_image("mydisk.dsk") as image:
    # Get volume information
    print(f"Volume: {image.get_volume_name()}")
    print(f"Format: {image.format}")
    
    # List all files
    files = image.get_file_list()
    for file_entry in files:
        print(f"{file_entry.filename} ({file_entry.size} bytes)")
        
        # Extract file
        data = file_entry.read_data()
        with open(file_entry.filename, 'wb') as f:
            f.write(data)

# Create a new blank disk
diskii.disk_creator.create_blank_prodos_image("new_disk.po", "MY.DISK")

# Add files to existing disk (requires read_only=False)
with diskii.open_disk_image("mydisk.po", read_only=False) as image:
    image.create_file("HELLO.TXT", 0x04, b"Hello from diskii!")

# BASIC program tokenization
import diskii

# Tokenize Applesoft BASIC program
program_text = '''10 HOME
20 PRINT "HELLO WORLD!"
30 END'''

tokenized = diskii.tokenize_applesoft(program_text)
detokenized = diskii.detokenize_applesoft(tokenized)

# Work with BASIC files on disk images
with diskii.open_disk_image("mydisk.po", read_only=False) as image:
    # Save as tokenized BASIC program
    image.create_file("HELLO.BAS", 0xFC, tokenized)
    
    # Read BASIC file and detokenize automatically
    files = image.get_file_list()
    for file_entry in files:
        if file_entry.is_basic_file():
            plain_text = file_entry.read_as_text()  # Auto-detokenizes
            raw_tokens = file_entry.read_as_tokens()  # Raw tokenized data

# BASIC syntax validation with ROM compliance
program_text = '''10 HOME
20 FOR I = 1 TO 10
30 PRINT "COUNT: "; I
40 NEXT I
50 END'''

# Validate Applesoft BASIC syntax
errors = diskii.validate_basic_syntax(program_text, "applesoft")
if not errors:
    print("✅ Program syntax is valid!")
else:
    for error in errors:
        print(f"Line {error.line}: {error.message}")

# Advanced syntax validation with custom validator
validator = diskii.BASICSyntaxValidator("applesoft")
errors = validator.validate_program(program_text)

# Validate Integer BASIC programs
integer_program = '''10 HOME
20 FOR I = 1 TO 10
30 PRINT "COUNT: "; I
40 NEXT I
50 END'''

# Also test Integer BASIC tokenization functions
tokenized_integer = diskii.tokenize_integer_basic(integer_program)
detokenized_integer = diskii.detokenize_integer_basic(tokenized_integer)

errors = diskii.validate_basic_syntax(integer_program, "integer")

Supported Formats

Extension Description Sector Ordering Supported Filesystems
.dsk DOS order disk images (140KB) DOS order DOS 3.3, ProDOS
.do DOS order disk images DOS order DOS 3.3, ProDOS
.po ProDOS order disk images ProDOS order DOS 3.3, ProDOS
.hdv ProDOS hard disk volumes (up to 32MB) ProDOS order ProDOS
.d13 DOS 3.2 13-sector images DOS 3.2 order DOS 3.2

Error Handling

diskii provides comprehensive error handling:

try:
    with diskii.open_disk_image("questionable.dsk") as image:
        files = image.get_file_list()
except diskii.UnrecognizedFormatError:
    print("Not a valid disk image")
except diskii.CorruptedImageError:
    print("Image appears to be corrupted")
except diskii.AccessError:
    print("Cannot access the image file")

Examples

The examples/ directory contains practical usage examples:

  • directory_tree.py: Display disk contents in tree format
  • file_info.py: Show detailed file metadata and type information
  • create_files.py: Demonstrate creating files on disk images
  • cross_format_copy.py: Copy files between ProDOS and DOS formats
  • basic_tokenization.py: BASIC program tokenization and detokenization examples

Requirements

  • Python 3.11+ (no upper version limit)
  • No external dependencies for core functionality

Development

# Install with development dependencies
poetry install --with dev,docs

# Run tests
poetry run pytest

# Run with coverage
poetry run pytest --cov=src/diskii

# Run CiderPress 2 compatibility tests
poetry run pytest -m integration

# Run fuzzing tests (requires dev dependencies)
python tests/fuzz/run_fuzz_tests.py

# Format code
poetry run ruff format src/ tests/

# Type checking  
poetry run mypy src/

# Build documentation
cd docs && make html

Planned Features

  • GUI application: Desktop interface for disk browsing and editing

Not Planned (Pull Requests Welcome)

  • WOZ image format support
  • 2MG image format support
  • NIB image format support
  • Pascal or CP/M filesystem support (test infrastructure added, implementation welcome)

References

License

ISC License - see LICENSE file for details.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

diskii-0.4.17.tar.gz (120.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

diskii-0.4.17-py3-none-any.whl (152.0 kB view details)

Uploaded Python 3

File details

Details for the file diskii-0.4.17.tar.gz.

File metadata

  • Download URL: diskii-0.4.17.tar.gz
  • Upload date:
  • Size: 120.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.13 Linux/6.18.29-0-lts

File hashes

Hashes for diskii-0.4.17.tar.gz
Algorithm Hash digest
SHA256 bc520a54da695e9beb9efa3dcb32df031258bb7dfcb6af872cc31f909f24630b
MD5 181279e15f819fb2e2f3f9c3ef43ca71
BLAKE2b-256 c139c95d9103aefc7f96134e400bb1c77477dc47eec1f47157a0e9008bf5d0b8

See more details on using hashes here.

File details

Details for the file diskii-0.4.17-py3-none-any.whl.

File metadata

  • Download URL: diskii-0.4.17-py3-none-any.whl
  • Upload date:
  • Size: 152.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.13 Linux/6.18.29-0-lts

File hashes

Hashes for diskii-0.4.17-py3-none-any.whl
Algorithm Hash digest
SHA256 f78ca8f88db52be6ec3546befbbbca6f52e703998e4826fc3fd794a7fca9bf21
MD5 21572f904b047e7639d1be18244cbe4b
BLAKE2b-256 b94b68d49985ab809e56171f56278397e53cc12e462854c91d84efb06e9f8092

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page