ponydos/assemble_floppy.py

65 lines
1.6 KiB
Python

import sys
import os.path
floppy_bytes = 1440 * 1024
sector_bytes = 512
dirent_bytes = 32
file_bytes = sector_bytes * 128
floppy = bytearray()
def extend_padded(buffer, alignment, data):
padding_len = (alignment - len(data)) % alignment
buffer.extend(data)
buffer.extend(bytes(padding_len))
if len(sys.argv) < 3:
print(f'Usage: {sys.argv[0]} disk.img bootsector.bin files…', file=sys.stderr)
sys.exit(1)
output_path = sys.argv[1]
bootsector_path = sys.argv[2]
files_paths = sys.argv[3:]
with open(bootsector_path, 'rb') as f:
bootsector = f.read()
assert len(bootsector) == sector_bytes
floppy.extend(bootsector)
files = []
directory = bytearray()
for file_path in files_paths:
with open(file_path, 'rb') as f:
file_contents = f.read()
assert len(file_contents) <= 128 * sector_bytes # 128 sector files
files.append(file_contents)
# dirent:
# 2 bytes size in 512B sectors, 0 for end of listing
# 30 bytes null-terminated name
sectors = (len(file_contents) + sector_bytes - 1) // sector_bytes
file_name = os.path.basename(file_path).encode() + b'\0'
assert len(file_name) <= 30
dirent = bytes([sectors & 0xff, sectors >> 8]) + file_name
extend_padded(directory, dirent_bytes, dirent)
## Add a zero dirent to mark the end of the directory
## (and the start of the consulate)
#directory.extend(bytes(dirent_bytes))
assert len(directory) <= sector_bytes
extend_padded(floppy, sector_bytes, directory)
for file_contents in files:
extend_padded(floppy, file_bytes, file_contents)
assert len(floppy) <= floppy_bytes
output = bytearray()
extend_padded(output, floppy_bytes, floppy)
with open(output_path, 'wb') as f:
f.write(output)