Last active
September 15, 2024 13:00
-
-
Save dillera/7192d884929aac1b9905ab478342dc28 to your computer and use it in GitHub Desktop.
Apple II Disk Type Detection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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