Created
July 13, 2025 12:24
-
-
Save t94xr/b959fafb1921c7147e87b8be40596470 to your computer and use it in GitHub Desktop.
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
| #!/usr/bin/env python3 | |
| # | |
| # This script creates a blank, formatted floppy disk image and mounts it. | |
| # It is based on the following disk geometry for a DOT Computer floppy disk: | |
| # | |
| # disk ibm.dot | |
| # cyls = 70 | |
| # heads = 1 | |
| # tracks * ibm.mfm | |
| # secs = 8 | |
| # bps = 512 | |
| # gap3 = 84 | |
| # rate = 250 | |
| # end | |
| # end | |
| # | |
| # Dependencies (Debian/Ubuntu): | |
| # - coreutils (for dd) | |
| # - dosfstools (for mkfs.fat) | |
| # - greaseweasel (optional, for writing to a physical disk) | |
| # | |
| # To install dependencies, run: | |
| # sudo apt-get update && sudo apt-get install -y coreutils dosfstools | |
| # | |
| import subprocess | |
| import sys | |
| import os | |
| def run_command(command, as_root=False): | |
| """A helper function to run a command and handle errors.""" | |
| if as_root and os.geteuid() != 0: | |
| command.insert(0, "sudo") | |
| print(f"Running command: {' '.join(command)}") | |
| try: | |
| process = subprocess.run( | |
| command, | |
| check=True, | |
| capture_output=True, | |
| text=True, | |
| ) | |
| # Print stdout or stderr from the command for more context. | |
| if process.stdout: | |
| print(process.stdout.strip()) | |
| if process.stderr: | |
| print(process.stderr.strip()) | |
| return True | |
| except FileNotFoundError: | |
| print(f"Error: '{command[0]}' command not found. Please ensure it is installed and in your PATH.", file=sys.stderr) | |
| return False | |
| except subprocess.CalledProcessError as e: | |
| print(f"Error executing command: {' '.join(command)}", file=sys.stderr) | |
| print(f"Return Code: {e.returncode}", file=sys.stderr) | |
| print(f"Stdout: {e.stdout.strip()}", file=sys.stderr) | |
| print(f"Stderr: {e.stderr.strip()}", file=sys.stderr) | |
| return False | |
| def main(): | |
| """ | |
| Creates a blank, formatted disk image and mounts it. | |
| """ | |
| # --- Configuration --- | |
| # The name of the disk image file to create. | |
| output_file = "blank_disk.img" | |
| # The size of the disk image in bytes, calculated from the disk geometry. | |
| # 70 cylinders * 1 head * 8 sectors/track * 512 bytes/sector | |
| image_size = 286720 | |
| # The path where the disk image will be mounted. | |
| mount_point = "/media/floppy.dot" | |
| # --- Step 1: Create a blank image file using dd --- | |
| # 'dd' is a core utility for copying and converting data. | |
| # We use it here to create a file of a specific size, filled with zeros. | |
| print("\n--- Step 1: Creating blank disk image ---") | |
| dd_command = ["dd", "if=/dev/zero", f"of={output_file}", "bs=1", f"count={image_size}"] | |
| if not run_command(dd_command): | |
| sys.exit(1) | |
| print("Blank image file created successfully.") | |
| # --- Step 2: Format the image with a FAT12 filesystem --- | |
| # 'mkfs.fat' creates a FAT (File Allocation Table) filesystem. | |
| # FAT12 is standard for floppy disks of this size. | |
| # We use the full path '/sbin/mkfs.fat' to avoid PATH issues. | |
| print("\n--- Step 2: Formatting the disk image ---") | |
| mkfs_command = ["/sbin/mkfs.fat", "-F", "12", output_file] | |
| if not run_command(mkfs_command): | |
| sys.exit(1) | |
| print("Image formatted successfully.") | |
| # --- Step 3: Create the mount point directory --- | |
| # The 'mkdir -p' command creates a directory, including any parent | |
| # directories that don't exist. This requires root privileges. | |
| print(f"\n--- Step 3: Creating mount point at {mount_point} ---") | |
| print("This step requires root privileges to create a directory in /media.") | |
| mkdir_command = ["mkdir", "-p", mount_point] | |
| if not run_command(mkdir_command, as_root=True): | |
| sys.exit(1) | |
| print("Mount point created successfully.") | |
| # --- Step 4: Mount the disk image --- | |
| # The 'mount' command attaches the filesystem on the image file to the | |
| # specified mount point. The '-o loop' option is used to mount a file | |
| # as if it were a block device. This also requires root privileges. | |
| print(f"\n--- Step 4: Mounting {output_file} to {mount_point} ---") | |
| print("This step requires root privileges to mount the image.") | |
| mount_command = ["mount", "-o", "loop", output_file, mount_point] | |
| if not run_command(mount_command, as_root=True): | |
| sys.exit(1) | |
| print(f"\nSuccess! The disk image '{output_file}' is now mounted on '{mount_point}'.") | |
| # --- Step 5: Write to a physical disk (Optional) --- | |
| # The following command can be used with Greaseweazle hardware to write | |
| # the created image file to a real floppy disk. | |
| # | |
| # IMPORTANT: This will erase all data on the floppy disk in the drive. | |
| # | |
| # You will need to: | |
| # 1. Have Greaseweazle installed and a device connected. | |
| # 2. Insert a blank floppy disk into your drive. | |
| # 3. Un-comment and run the command below, replacing 'A' with your drive letter if needed. | |
| # | |
| # print("\n--- Optional: Write to physical disk ---") | |
| # gw_command = ["gw", "write", output_file, "--drive=A"] | |
| # if not run_command(gw_command): | |
| # print("Failed to write to physical disk.", file=sys.stderr) | |
| # | |
| if __name__ == "__main__": | |
| # This check ensures the main function is called only when the script is executed directly. | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment