adf.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. import struct
  8. from greaseweazle import error
  9. from greaseweazle.track import MasterTrack
  10. from greaseweazle.bitcell import Bitcell
  11. import greaseweazle.codec.amiga.amigados as amigados
  12. from bitarray import bitarray
  13. class ADF:
  14. default_format = 'amiga.amigados'
  15. def __init__(self, start_cyl, nr_sides):
  16. error.check(nr_sides == 2, "ADF: Must be double-sided")
  17. self.bitrate = 253
  18. self.sec_per_track = 11
  19. self.track_list = [None] * start_cyl
  20. @classmethod
  21. def to_file(cls, start_cyl, nr_sides):
  22. adf = cls(start_cyl, nr_sides)
  23. return adf
  24. @classmethod
  25. def from_file(cls, dat):
  26. adf = cls(0, 2)
  27. nsec = adf.sec_per_track
  28. error.check((len(dat) % (2*nsec*512)) == 0, "Bad ADF image")
  29. ncyl = len(dat) // (2*nsec*512)
  30. if ncyl > 90:
  31. ncyl //= 2
  32. nsec *= 2
  33. adf.bitrate *= 2
  34. adf.sec_per_track = nsec
  35. for i in range(ncyl*2):
  36. ados = amigados.AmigaDOS(tracknr=i, nsec=nsec)
  37. ados.set_adf_track(dat[i*nsec*512:(i+1)*nsec*512])
  38. adf.track_list.append(ados)
  39. return adf
  40. def get_track(self, cyl, side, writeout=False):
  41. off = cyl * 2 + side
  42. if off >= len(self.track_list):
  43. return None
  44. rawbytes = self.track_list[off].bits()
  45. tdat = bitarray(endian='big')
  46. tdat.frombytes(rawbytes)
  47. track = MasterTrack(
  48. bits = tdat,
  49. time_per_rev = 0.2)
  50. track.verify = self.track_list[off]
  51. return track
  52. def append_track(self, track):
  53. self.track_list.append(track)
  54. def get_image(self):
  55. tlen = self.sec_per_track * 512
  56. tdat = bytearray()
  57. for t in self.track_list:
  58. if t is None or not hasattr(t, 'get_adf_track'):
  59. tdat += bytes(tlen)
  60. else:
  61. tdat += t.get_adf_track()
  62. if len(self.track_list) < 160:
  63. tdat += bytes(tlen * (160 - len(self.track_list)))
  64. return tdat
  65. # Local variables:
  66. # python-indent: 4
  67. # End: