adf.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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, start_cyl, nr_sides):
  13. error.check(nr_sides == 2, "ADF: Must be double-sided")
  14. self.sec_per_track = 11
  15. self.track_list = [None] * start_cyl
  16. @classmethod
  17. def from_file(cls, name):
  18. with open(name, "rb") as f:
  19. dat = f.read()
  20. adf = cls(0, 2)
  21. nsec = adf.sec_per_track
  22. error.check((len(dat) % (2*nsec*512)) == 0, "Bad ADF image")
  23. ncyl = len(dat) // (2*nsec*512)
  24. if ncyl > 90:
  25. ncyl //= 2
  26. nsec *= 2
  27. adf.sec_per_track = nsec
  28. for i in range(ncyl*2):
  29. ados = amigados.AmigaDOS(tracknr=i, nsec=nsec)
  30. ados.set_adf_track(dat[i*nsec*512:(i+1)*nsec*512])
  31. adf.track_list.append(ados)
  32. return adf
  33. def get_track(self, cyl, side):
  34. off = cyl * 2 + side
  35. if off >= len(self.track_list):
  36. return None
  37. return self.track_list[off].raw_track()
  38. def append_track(self, track):
  39. self.track_list.append(track)
  40. def get_image(self):
  41. tlen = self.sec_per_track * 512
  42. tdat = bytearray()
  43. for tracknr in range(len(self.track_list)):
  44. t = self.track_list[tracknr]
  45. if t is not None and hasattr(t, 'get_adf_track'):
  46. tdat += t.get_adf_track()
  47. elif tracknr < 160:
  48. # Pad empty/damaged tracks.
  49. tdat += bytes(tlen)
  50. else:
  51. # Do not extend past 160 tracks unless there is data.
  52. break
  53. if len(self.track_list) < 160:
  54. tdat += bytes(tlen * (160 - len(self.track_list)))
  55. return tdat
  56. # Local variables:
  57. # python-indent: 4
  58. # End: