1515#include " STFactory.h"
1616#include " CoreError.h"
1717#include " DeviceError.h"
18+ #include " MFM.h"
1819
1920namespace vamiga {
2021
21- void
22- DiskEncoder::encodeMFM (u8 *dst, const u8 *src, isize count)
23- {
24- for (isize i = 0 ; i < count; i++) {
25-
26- auto mfm =
27- ((src[i] & 0b10000000 ) << 7 ) |
28- ((src[i] & 0b01000000 ) << 6 ) |
29- ((src[i] & 0b00100000 ) << 5 ) |
30- ((src[i] & 0b00010000 ) << 4 ) |
31- ((src[i] & 0b00001000 ) << 3 ) |
32- ((src[i] & 0b00000100 ) << 2 ) |
33- ((src[i] & 0b00000010 ) << 1 ) |
34- ((src[i] & 0b00000001 ) << 0 );
35-
36- dst[2 *i+0 ] = HI_BYTE (mfm);
37- dst[2 *i+1 ] = LO_BYTE (mfm);
38- }
39- }
40-
41- void
42- DiskEncoder::decodeMFM (u8 *dst, const u8 *src, isize count)
43- {
44- for (isize i = 0 ; i < count; i++) {
45-
46- u16 mfm = HI_LO (src[2 *i], src[2 *i+1 ]);
47-
48- auto decoded =
49- ((mfm & 0b0100000000000000 ) >> 7 ) |
50- ((mfm & 0b0001000000000000 ) >> 6 ) |
51- ((mfm & 0b0000010000000000 ) >> 5 ) |
52- ((mfm & 0b0000000100000000 ) >> 4 ) |
53- ((mfm & 0b0000000001000000 ) >> 3 ) |
54- ((mfm & 0b0000000000010000 ) >> 2 ) |
55- ((mfm & 0b0000000000000100 ) >> 1 ) |
56- ((mfm & 0b0000000000000001 ) >> 0 );
57-
58- dst[i] = (u8 )decoded;
59- }
60- }
61-
62- void
63- DiskEncoder::encodeOddEven (u8 *dst, const u8 *src, isize count)
64- {
65- // Encode odd bits
66- for (isize i = 0 ; i < count; i++)
67- dst[i] = (src[i] >> 1 ) & 0x55 ;
68-
69- // Encode even bits
70- for (isize i = 0 ; i < count; i++)
71- dst[i + count] = src[i] & 0x55 ;
72- }
73-
74- void
75- DiskEncoder::decodeOddEven (u8 *dst, const u8 *src, isize count)
76- {
77- // Decode odd bits
78- for (isize i = 0 ; i < count; i++)
79- dst[i] = (u8 )((src[i] & 0x55 ) << 1 );
80-
81- // Decode even bits
82- for (isize i = 0 ; i < count; i++)
83- dst[i] |= src[i + count] & 0x55 ;
84- }
85-
86- void
87- DiskEncoder::addClockBits (u8 *dst, isize count)
88- {
89- for (isize i = 0 ; i < count; i++) {
90- dst[i] = addClockBits (dst[i], dst[i-1 ]);
91- }
92- }
93-
94- u8
95- DiskEncoder::addClockBits (u8 value, u8 previous)
96- {
97- // Clear all previously set clock bits
98- value &= 0x55 ;
99-
100- // Compute clock bits (clock bit values are inverted)
101- u8 lShifted = (u8 )(value << 1 );
102- u8 rShifted = (u8 )(value >> 1 | previous << 7 );
103- u8 cBitsInv = (u8 )(lShifted | rShifted);
104-
105- // Reverse the computed clock bits
106- u8 cBits = cBitsInv ^ 0xAA ;
107-
108- // Return original value with the clock bits added
109- return value | cBits;
110- }
111-
11222void
11323DiskEncoder::encodeAmigaTrack (MutableByteView track, TrackNr t, ByteView src)
11424{
@@ -166,14 +76,14 @@ DiskEncoder::encodeAmigaSector(MutableByteView track, isize offset, TrackNr t, S
16676
16777 // Track and sector information
16878 u8 info[4 ] = { 0xFF , (u8 )t, (u8 )s, (u8 )(11 - s) };
169- encodeOddEven (&it[8 ], info, sizeof (info));
79+ MFM:: encodeOddEven (&it[8 ], info, sizeof (info));
17080
17181 // Unused area
17282 for (isize i = 16 ; i < 48 ; i++)
17383 it[i] = 0xAA ;
17484
17585 // Data
176- encodeOddEven (&it[64 ], data.data (), bsize);
86+ MFM:: encodeOddEven (&it[64 ], data.data (), bsize);
17787
17888 // Block checksum
17989 u8 bcheck[4 ] = { 0 , 0 , 0 , 0 };
@@ -183,7 +93,7 @@ DiskEncoder::encodeAmigaSector(MutableByteView track, isize offset, TrackNr t, S
18393 bcheck[2 ] ^= it[i+2 ];
18494 bcheck[3 ] ^= it[i+3 ];
18595 }
186- encodeOddEven (&it[48 ], bcheck, sizeof (bcheck));
96+ MFM:: encodeOddEven (&it[48 ], bcheck, sizeof (bcheck));
18797
18898 // Data checksum
18999 u8 dcheck[4 ] = { 0 , 0 , 0 , 0 };
@@ -193,11 +103,11 @@ DiskEncoder::encodeAmigaSector(MutableByteView track, isize offset, TrackNr t, S
193103 dcheck[2 ] ^= it[i+2 ];
194104 dcheck[3 ] ^= it[i+3 ];
195105 }
196- encodeOddEven (&it[56 ], dcheck, sizeof (dcheck));
106+ MFM:: encodeOddEven (&it[56 ], dcheck, sizeof (dcheck));
197107
198108 // Add clock bits
199109 for (isize i = 8 ; i < ssize + 1 ; i++) {
200- it[i] = addClockBits (it[i], it[i-1 ]);
110+ it[i] = MFM:: addClockBits (it[i], it[i-1 ]);
201111 }
202112}
203113
@@ -213,19 +123,6 @@ DiskEncoder::decodeAmigaTrack(ByteView track, TrackNr t, MutableByteView dst)
213123 // Find all sectors
214124 auto offsets = seekSectors (track);
215125
216- /*
217- for (isize i = 0; i < count; ++i) {
218- if (!offsets.contains(i)) {
219- warn("Sector %ld not found. Aborting.\n", i);
220- throw DeviceError(DeviceError::DEV_SEEK_ERR);
221- }
222- }
223- if (isize(offsets.size()) != count) {
224- warn("Found %zd sectors, expected %ld. Aborting.\n", offsets.size(), count);
225- throw DeviceError(DeviceError::DSK_WRONG_SECTOR_COUNT);
226- }
227- */
228-
229126 // Decode all sectors
230127 for (SectorNr s = 0 ; s < count; s++) {
231128
@@ -253,13 +150,8 @@ DiskEncoder::decodeAmigaSector(ByteView track, isize offset, MutableByteView dst
253150 // Determine the source address
254151 auto *mfmData = &track[offset];
255152
256- for (isize i = 0 ; i < 16 ; ++i) { printf (" %0X " , mfmData[i]); } printf (" \n " );
257-
258-
259153 // Decode sector data
260- decodeOddEven (dst.data (), mfmData, bsize);
261-
262- for (isize i = 0 ; i < 8 ; ++i) { printf (" %0X " , dst.data ()[i]); } printf (" \n " );
154+ MFM::decodeOddEven (dst.data (), mfmData, bsize);
263155}
264156
265157optional<isize>
@@ -282,7 +174,7 @@ DiskEncoder::trySeekSector(ByteView track, SectorNr s, isize offset)
282174 if (it[5 ] == 0x89 ) continue ;
283175
284176 // Decode track & sector info
285- u8 info[4 ]; decodeOddEven (info, &it[4 ], 4 );
177+ u8 info[4 ]; MFM:: decodeOddEven (info, &it[4 ], 4 );
286178
287179 // Check if the sector number matches
288180 if (info[2 ] == s) return it.offset ();
@@ -321,7 +213,7 @@ DiskEncoder::seekSectors(ByteView track)
321213 if (it[5 ] == 0x89 ) continue ;
322214
323215 // Decode track & sector info (info[2] = sector number)
324- u8 info[4 ]; decodeOddEven (info, &it[4 ], 4 );
216+ u8 info[4 ]; MFM:: decodeOddEven (info, &it[4 ], 4 );
325217
326218 // Record the offset
327219 result[info[2 ]] = it.offset ();
@@ -358,10 +250,9 @@ DiskEncoder::encode(const ADFFile &adf, FloppyDisk &disk)
358250 // In debug mode, also run the decoder
359251 if (ADF_DEBUG) {
360252
361- auto adf = ADFFactory::make (disk);
362253 string tmp = " /tmp/debug.adf" ;
363254 fprintf (stderr, " Saving image to %s for debugging\n " , tmp.c_str ());
364- adf ->writeToFile (tmp);
255+ ADFFactory::make (disk) ->writeToFile (tmp);
365256 }
366257}
367258
@@ -379,12 +270,7 @@ void DiskEncoder::decode(ADFFile &adf, const class FloppyDisk &disk)
379270 throw DeviceError (DeviceError::DSK_INVALID_DENSITY);
380271 }
381272
382- // Make the MFM stream scannable beyond the track end
383- // TODO: THINK ABOUT OF DECODING WITHOUT MODIFYING THE DISK
384- // const_cast<FloppyDisk &>(disk).repeatTracks();
385-
386273 // Decode all tracks
387- // for (Track t = 0; t < tracks; t++) decodeTrack(adf, disk, t);
388274 for (TrackNr t = 0 ; t < tracks; t++)
389275 decodeAmigaTrack (disk.byteView (t), t, adf.byteView (t));
390276}
@@ -522,8 +408,8 @@ DiskEncoder::encodeSector(const IMGFile &img, FloppyDisk &disk, TrackNr t, Secto
522408 u8 *p = disk.data .track [t] + 194 + s * 1300 ;
523409
524410 // Create the MFM data stream
525- encodeMFM (p, buf, sizeof (buf));
526- addClockBits (p, 2 * sizeof (buf));
411+ MFM:: encodeMFM (p, buf, sizeof (buf));
412+ MFM:: addClockBits (p, 2 * sizeof (buf));
527413
528414 // Remove certain clock bits in IDAM block
529415 p[2 *12 +1 ] &= 0xDF ;
@@ -567,7 +453,7 @@ DiskEncoder::decodeTrack(IMGFile &img, const class FloppyDisk &disk, TrackNr t)
567453
568454 // Decode CHRN block
569455 struct { u8 c; u8 h; u8 r; u8 n; } chrn;
570- decodeMFM ((u8 *)&chrn, &src[i], 4 );
456+ MFM:: decodeMFM ((u8 *)&chrn, &src[i], 4 );
571457 if (IMG_DEBUG) fprintf (stderr, " c: %d h: %d r: %d n: %d\n " , chrn.c , chrn.h , chrn.r , chrn.n );
572458
573459 if (chrn.r >= 1 && chrn.r <= numSectors) {
@@ -600,7 +486,7 @@ DiskEncoder::decodeTrack(IMGFile &img, const class FloppyDisk &disk, TrackNr t)
600486void
601487DiskEncoder::decodeSector (IMGFile &img, u8 *dst, const u8 *src)
602488{
603- decodeMFM (dst, src, 512 );
489+ MFM:: decodeMFM (dst, src, 512 );
604490}
605491
606492
@@ -737,8 +623,8 @@ DiskEncoder::encodeSector(const STFile &img, FloppyDisk &disk, TrackNr t, Sector
737623 u8 *p = disk.data .track [t] + 194 + s * 1300 ;
738624
739625 // Create the MFM data stream
740- encodeMFM (p, buf, sizeof (buf));
741- addClockBits (p, 2 * sizeof (buf));
626+ MFM:: encodeMFM (p, buf, sizeof (buf));
627+ MFM:: addClockBits (p, 2 * sizeof (buf));
742628
743629 // Remove certain clock bits in IDAM block
744630 p[2 *12 +1 ] &= 0xDF ;
@@ -782,7 +668,7 @@ DiskEncoder::decodeTrack(STFile &img, const class FloppyDisk &disk, TrackNr t)
782668
783669 // Decode CHRN block
784670 struct { u8 c; u8 h; u8 r; u8 n; } chrn;
785- decodeMFM ((u8 *)&chrn, &src[i], 4 );
671+ MFM:: decodeMFM ((u8 *)&chrn, &src[i], 4 );
786672 if (IMG_DEBUG) fprintf (stderr, " c: %d h: %d r: %d n: %d\n " , chrn.c , chrn.h , chrn.r , chrn.n );
787673
788674 if (chrn.r >= 1 && chrn.r <= numSectors) {
@@ -815,7 +701,7 @@ DiskEncoder::decodeTrack(STFile &img, const class FloppyDisk &disk, TrackNr t)
815701void
816702DiskEncoder::decodeSector (STFile &img, u8 *dst, const u8 *src)
817703{
818- decodeMFM (dst, src, 512 );
704+ MFM:: decodeMFM (dst, src, 512 );
819705}
820706
821707
0 commit comments