adf.py 2.2 KB

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