adf.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. # greaseweazle/image/adf.py
  2. #
  3. # Written & released by Keir Fraser <keir.xen@gmail.com>
  4. #
  5. # This is free and unencumbered software released into the public domain.
  6. # See the file COPYING for more details, or visit <http://unlicense.org>.
  7. from greaseweazle import error
  8. import greaseweazle.codec.amiga.amigados as amigados
  9. from .image import Image
  10. class ADF(Image):
  11. default_format = 'amiga.amigados'
  12. def __init__(self):
  13. self.sec_per_track = 11
  14. self.to_track = dict()
  15. @classmethod
  16. def from_file(cls, name):
  17. with open(name, "rb") as f:
  18. dat = f.read()
  19. adf = cls()
  20. nsec = adf.sec_per_track
  21. error.check((len(dat) % (2*nsec*512)) == 0, "Bad ADF image")
  22. ncyl = len(dat) // (2*nsec*512)
  23. if ncyl > 90:
  24. ncyl //= 2
  25. nsec *= 2
  26. adf.sec_per_track = nsec
  27. for tnr in range(ncyl*2):
  28. ados = amigados.AmigaDOS(tracknr=tnr, nsec=nsec)
  29. ados.set_adf_track(dat[tnr*nsec*512:(tnr+1)*nsec*512])
  30. adf.to_track[tnr] = ados
  31. return adf
  32. def get_track(self, cyl, side):
  33. tnr = cyl * 2 + side
  34. if not tnr in self.to_track:
  35. return None
  36. return self.to_track[tnr].raw_track()
  37. def emit_track(self, cyl, side, track):
  38. tnr = cyl * 2 + side
  39. self.to_track[tnr] = track
  40. def get_image(self):
  41. tlen = self.sec_per_track * 512
  42. tdat = bytearray()
  43. ntracks = max(self.to_track, default=0) + 1
  44. for tnr in range(ntracks):
  45. t = self.to_track[tnr] if tnr in self.to_track else None
  46. if t is not None and hasattr(t, 'get_adf_track'):
  47. tdat += t.get_adf_track()
  48. elif tnr < 160:
  49. # Pad empty/damaged tracks.
  50. tdat += bytes(tlen)
  51. else:
  52. # Do not extend past 160 tracks unless there is data.
  53. break
  54. if ntracks < 160:
  55. tdat += bytes(tlen * (160 - ntracks))
  56. return tdat
  57. # Local variables:
  58. # python-indent: 4
  59. # End: