Skip to content

Instantly share code, notes, and snippets.

@dillera
Last active September 15, 2024 13:00
Show Gist options
  • Save dillera/7192d884929aac1b9905ab478342dc28 to your computer and use it in GitHub Desktop.
Save dillera/7192d884929aac1b9905ab478342dc28 to your computer and use it in GitHub Desktop.
Apple II Disk Type Detection
Apple 2 disk help
1. Format and Size Detection:
• is_woz_format: Checks if the disk image starts with the WOZ signature.
• get_image_size_kb: Retrieves the size of the disk image in kilobytes.
2. Filesystem Detection:
• detect_filesystem: Utilizes the existing autodetection to identify the filesystem and sector order.
3. Recommendation Logic:
• recommend_mounting: Implements the mounting recommendation rules based on image format, size, and filesystem.
• Adds warnings if the recommended mounting might not align with the detected filesystem.
4. Mounting Process:
• mount_image: Placeholder function where you would integrate the actual mounting logic (e.g., interfacing with emulators or system mounts).
• mounting_assistant: Orchestrates the detection, recommendation, warning display, and mounting process. It also handles user overrides.
5. User Interaction:
• Prompts the user with warnings and seeks confirmation before proceeding.
• Allows the user to override the mounting recommendation if necessary.
---------------------------------------------------
import os
# Constants for sector orders
SECTOR_ORDER_PRODOS = 'High-to-Low'
SECTOR_ORDER_DOS33 = 'Low-to-High'
# Constants for mounting types
MOUNT_DISKII = 'Disk II'
MOUNT_SMARTPORT = 'SmartPort'
# Define ProDOS and DOS 3.3 boot sector signatures
PRODOS_SIGNATURE = b'PRODOS'
DOS33_SIGNATURE = b'DOS33'
# Define WOZ signature (example placeholder)
WOZ_SIGNATURE = b'WOZ\x1A'
def is_woz_format(disk_image):
# Check if the disk image starts with the WOZ signature
return disk_image.startswith(WOZ_SIGNATURE)
def get_image_size_kb(file_path):
size_bytes = os.path.getsize(file_path)
return size_bytes / 1024
def read_sector(disk_image, sector_size, sector_order, sector_number):
if sector_order == 'ProDOS':
# Implement high-to-low sector ordering
# Example logic: reverse sector numbering
sector_index = sector_number # Placeholder
elif sector_order == 'DOS33':
# Implement low-to-high sector ordering
sector_index = sector_number # Placeholder
else:
raise ValueError("Unknown sector order")
return disk_image[sector_index * sector_size : (sector_index + 1) * sector_size]
def detect_filesystem(disk_image, sector_size=512):
# Attempt ProDOS detection
prodos_boot = read_sector(disk_image, sector_size, 'ProDOS', 0)
if PRODOS_SIGNATURE in prodos_boot:
return 'ProDOS', SECTOR_ORDER_PRODOS
# Attempt DOS 3.3 detection
dos33_boot = read_sector(disk_image, sector_size, 'DOS33', 0)
if DOS33_SIGNATURE in dos33_boot:
return 'DOS33_RWTS', SECTOR_ORDER_DOS33
return 'Unknown', 'Unknown'
---------------------------------------------
Mounting Assistant
---------------------------------------------
def recommend_mounting(file_path):
with open(file_path, 'rb') as f:
disk_data = f.read()
image_size_kb = get_image_size_kb(file_path)
is_woz = is_woz_format(disk_data)
filesystem, sector_order = detect_filesystem(disk_data)
recommendation = None
warnings = []
# Mounting logic based on rules
if is_woz:
recommendation = MOUNT_DISKII
elif image_size_kb > 140:
recommendation = MOUNT_SMARTPORT
elif image_size_kb == 140:
if filesystem == 'ProDOS':
recommendation = MOUNT_SMARTPORT
else:
recommendation = MOUNT_DISKII
else:
# Handle unexpected sizes
recommendation = MOUNT_DISKII
warnings.append("Unexpected image size. Defaulting to Disk II.")
# Additional warning if user attempts to mount 140kB as SmartPort without ProDOS
if image_size_kb == 140 and filesystem != 'ProDOS':
warnings.append("140kB image without ProDOS detected. Disk II is recommended.")
return {
'recommendation': recommendation,
'filesystem': filesystem,
'sector_order': sector_order,
'warnings': warnings
}
def mount_image(file_path, mount_type, override=False):
# Implement the mounting logic based on mount_type
# This is a placeholder for actual mounting code
print(f"Mounting {file_path} as {mount_type}...")
# Example: call system commands or use libraries to mount
# If override is False and warnings exist, prevent mounting
pass
def mounting_assistant(file_path):
recommendation_info = recommend_mounting(file_path)
recommendation = recommendation_info['recommendation']
filesystem = recommendation_info['filesystem']
sector_order = recommendation_info['sector_order']
warnings = recommendation_info['warnings']
print(f"Detected Filesystem: {filesystem}")
print(f"Sector Order: {sector_order}")
print(f"Mounting Recommendation: {recommendation}")
if warnings:
print("Warnings:")
for warning in warnings:
print(f"- {warning}")
user_input = input("Do you want to proceed with the recommended mounting? (y/n): ")
if user_input.lower() != 'y':
print("Mounting canceled by user.")
return
else:
print("Proceeding with mounting.")
# Proceed with mounting as per recommendation
mount_image(file_path, recommendation)
# Optionally, allow user to override the recommendation
override_input = input("Do you want to override the mounting recommendation? (y/n): ")
if override_input.lower() == 'y':
user_mount_type = input(f"Enter mounting type ({MOUNT_DISKII}/{MOUNT_SMARTPORT}): ")
if user_mount_type in [MOUNT_DISKII, MOUNT_SMARTPORT]:
mount_image(file_path, user_mount_type, override=True)
else:
print("Invalid mounting type. Mounting aborted.")
else:
print("Mounting completed as recommended.")
# Example usage
if __name__ == "__main__":
disk_image_path = 'path/to/disk_image.dsk'
mounting_assistant(disk_image_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment