Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import struct, sys, cStringIO, os
from edoslib import *
def decodebits(s):
cs = cStringIO.StringIO(s)
res = ""
while True:
t = "01"
while True:
c = cs.read(1)
if len(c) == 0:
res += t
return res
if c == "1":
t += "1"
else:
break
res += t
c = cs.read(1)
if len(c) == 0:
break
if c == "1":
res += "0"
return res
def g64maker(tracks):
numtracks = 84
header = "GCR-1541" + struct.pack("<BBH", 0, numtracks, 0x1ef8)
dataoffset = 12 + numtracks * 8
datablock = ""
speedblock = ""
for i in xrange(numtracks):
half = i % 2
trackno = i / 2
if half == 1 or trackno not in tracks:
header += struct.pack("<I", 0)
speedblock += struct.pack("<I", 0)
else:
data = ""
track = tracks[trackno]
for j in xrange(0, len(track), 8):
c = track[j:j+8].ljust(8, "0")
data += chr(int(c, 2))
data = struct.pack("<H", len(data)) + data
#assert len(data) <= 0x1ef8
data = data.ljust(0x1ef8, "\xff")
size = len(data)
speed = (3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)[trackno]
header += struct.pack("<I", dataoffset)
speedblock += struct.pack("<I", speed)
datablock += data
dataoffset += size
return header + speedblock + datablock
class Track(object):
def __init__(self, trackno, dunno1, dunno2 , dunno3, format, dunno4, data):
self.trackno = trackno
self.dunno1 = dunno1
self.dunno2 = dunno2
self.dunno3 = dunno3
self.format = format
self.dunno4 = dunno4
self.data = data
def edos_parser(filename):
f = open(filename, "rb")
ct = f.read(512)
pt = decryptmetadata(ct)
metadata = pt.split("\xf7")
headersize = struct.unpack("<H", f.read(2))[0]
headerdata = f.read(headersize)
disks = []
currentdisk = 0
disks.append({})
for i in xrange(0, headersize, 10):
trackno, dunno1, dunno2, dunno3, sz, format, dunno4 = struct.unpack(">BBHHHBB", headerdata[i:i+10])
assert trackno >= 0 and trackno <= 40
assert format in (0x60, 0xe0, 0x7e)
if format == 0x7e:
assert dunno1 in (0, 1)
assert dunno2 == 3
assert dunno3 in (10, 4096)
else:
assert dunno1 == 0
assert dunno2 == 8
assert dunno3 == 10
assert dunno4 == 0
data = f.read(sz)
assert len(data) == sz
if format == 0x7e:
currentdisk += 1
disks.append({})
else:
assert trackno not in disks[currentdisk]
disks[currentdisk][trackno] = Track(trackno, dunno1, dunno2, dunno3, format, dunno4, data)
assert f.read() == ""
return metadata, disks
for filename in os.listdir("c64disk"):
sourcename = os.path.join("c64disk", filename)
basename = filename.split(".")[0]
metadata, disks = edos_parser(sourcename)
print filename, repr(metadata[0])
for i in xrange(len(disks)):
if len(disks) == 1:
ext = ".g64"
else:
ext = "_%d.g64" % (i + 1)
targetname = os.path.join("c64disk_converted", basename + ext)
if os.path.isfile(targetname):
continue
disk = disks[i]
tracks = {}
for trackno in disk:
track = disk[trackno]
if track.format == 0x60:
bits = ""
for cc in track.data:
c = ord(cc)
if c < 0x4c:
bits += "1"
elif c < 0x87:
bits += "01"
else:
bits += "001"
trackdata = bits
elif track.format == 0xe0:
bits = ""
for c in track.data:
for j in xrange(8):
if (ord(c) >> (j)) & 1 == 1:
bits += "1"
else:
bits += "0"
trackdata = decodebits(bits)
else:
print "BAD FORMAT TYPE"
exit()
assert trackno not in tracks
tracks[trackno] = trackdata
res = g64maker(tracks)
open(targetname, "wb").write(res)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment