Skip to content

Instantly share code, notes, and snippets.

@arpruss
Created January 8, 2026 22:26
Show Gist options
  • Select an option

  • Save arpruss/1f5cb19f1787dff04e407b10e01da07a to your computer and use it in GitHub Desktop.

Select an option

Save arpruss/1f5cb19f1787dff04e407b10e01da07a to your computer and use it in GitHub Desktop.
lif2xml.py
import sys
inName = sys.argv[1]
if inName.lower().endswith(".lif"):
outName = inName[:-3]+"xml"
else:
outName = inName+".xml"
inName = inName+".lif"
print("Converting",inName,"to",outName)
SECTOR_SIZE = 1024
SECTORS_PER_TRACK = 5
SIDES = 2
TRACKS = 80
SPECIAL_TRACK_START = 79
SPECIAL_SECTOR_START = 97
NORMAL_SECTOR_START = 1
HEADER = """<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- HxC Floppy Emulator Disk Layout -->
<disk_layout>
<disk_layout_name>AUTOGENERATEDLAYOUT</disk_layout_name>
<disk_layout_description>Auto Generated Disk Layout</disk_layout_description>
<prefered_file_extension>img</prefered_file_extension>
<interface_mode>GENERIC_SHUGART_DD_FLOPPYMODE</interface_mode>
<write_protected>0</write_protected>
<file_size>819200</file_size>
<layout>
<number_of_track>80</number_of_track>
<number_of_side>2</number_of_side>
<format>IBM_MFM</format>
<start_sector_id>1</start_sector_id>
<sector_per_track>5</sector_per_track>
<sector_size>1024</sector_size>
<formatvalue>0</formatvalue>
<gap3>255</gap3>
<bitrate>500000</bitrate>
<pregap>0</pregap>
<rpm>597</rpm>
<crc32>0x80C0B12B</crc32>
<track_list>
"""
TRACK_HEADER = """ <track track_number="%02u" side_number="%u">
<data_offset>0x%06x</data_offset>
<format>IBM_MFM</format>
<sector_list>
"""
SECTOR_DATA = """ <sector sector_id="%u" sector_size="%u">
<sector_data>%s</sector_data>
<datamark>0xFB</datamark>
<data_offset>0x%06x</data_offset>
</sector>
"""
with open(inName, "rb") as inF:
with open(outName, "w") as outF:
outF.write(HEADER)
for track in range(TRACKS):
for side in range(SIDES):
trackDataOffset = (track*SIDES*SECTORS_PER_TRACK + side*SECTORS_PER_TRACK) * SECTOR_SIZE
outF.write(TRACK_HEADER % (track,side,trackDataOffset))
for sector in range(5):
sectorData = inF.read(SECTOR_SIZE)
if len(sectorData) == 0:
sectorData = SECTOR_SIZE * bytes(b'\xFF')
sectorNumber = (SPECIAL_SECTOR_START if track>=SPECIAL_TRACK_START else NORMAL_SECTOR_START) + sector
outF.write(SECTOR_DATA % (sectorNumber, SECTOR_SIZE,sectorData.hex(), trackDataOffset + sector * SECTOR_SIZE))
outF.write(" </sector_list>\n")
outF.write(" </track>\n")
outF.write(""" </track_list>
</layout>
</disk_layout>""")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment