--- /home/markw/Downloads/atx.c	2018-08-31 22:21:40.347807773 +0200
+++ atx.c	2018-09-01 14:35:20.121479335 +0200
@@ -19,12 +19,8 @@
 //
 //*****************************************************************************
 
-#include <stdlib.h>
-#include <avr/io.h>
-#include <util/delay.h>
-#include "avrlibtypes.h"
+#include "atx_eclaire.h"
 #include "atx.h"
-#include "fat.h"
 
 // number of angular units in a full disk rotation
 #define AU_FULL_ROTATION         26042
@@ -52,17 +48,55 @@
 
 u16 gBytesPerSector;                    // number of bytes per sector
 u08 gSectorsPerTrack;                   // number of sectors in each track
-struct atxTrackInfo gTrackInfo[2][40];  // pre-calculated info for each track and drive
-                                        // support slot D1 and D2 only because of insufficient RAM!
-u16 gLastAngle = 0;
-u08 gCurrentHeadTrack = 1;
+struct atxTrackInfo gTrackInfo[40];     // pre-calculated info for each track
+u16 gLastAngle;
+u08 gCurrentHeadTrack;
+
+#define FILE_ACCESS_READ 0
+
+void longbyteswap(u32 * x);
+void byteswap(u16 * x);
+
+void byteswapatxfileheader(struct atxFileHeader * header)
+{
+    // only swap the used entries
+    byteswap(&header->version);
+    byteswap(&header->minVersion);
+    longbyteswap(&header->startData);
+}
+
+void byteswapatxtrackheader(struct atxTrackHeader * header)
+{
+    // only swap the used entries
+    longbyteswap(&header->size); // used
+    byteswap(&header->sectorCount); // used
+    longbyteswap(&header->headerSize); // used
+}
+
+void byteswapatxsectorlistheader(struct atxSectorListHeader * header)
+{
+	longbyteswap(&header->next);
+}
+
+void byteswapatxsectorheader(struct atxSectorHeader * header)
+{
+	byteswap(&header->timev);
+	longbyteswap(&header->data);
+}
 
-u16 loadAtxFile(u08 drive) {
+void byteswapatxtrackchunk(struct atxTrackChunk *header)
+{
+	byteswap(&header->data);
+	longbyteswap(&header->size);
+}
+
+u16 loadAtxFile() {
     struct atxFileHeader *fileHeader;
     struct atxTrackHeader *trackHeader;
 
     // read the file header
     faccess_offset(FILE_ACCESS_READ, 0, sizeof(struct atxFileHeader));
+    byteswapatxfileheader((struct atxFileHeader *) atari_sector_buffer);
 
     // validate the ATX file header
     fileHeader = (struct atxFileHeader *) atari_sector_buffer;
@@ -72,6 +106,7 @@
         fileHeader->signature[3] != 'X' ||
         fileHeader->version != ATX_VERSION ||
         fileHeader->minVersion != ATX_VERSION) {
+
         return 0;
     }
 
@@ -87,14 +122,15 @@
             break;
         }
         trackHeader = (struct atxTrackHeader *) atari_sector_buffer;
-        gTrackInfo[drive][trackHeader->trackNumber].offset = startOffset;
+	byteswapatxtrackheader(trackHeader);
+        gTrackInfo[trackHeader->trackNumber].offset = startOffset;
         startOffset += trackHeader->size;
     }
 
     return gBytesPerSector;
 }
 
-u16 loadAtxSector(u08 drive, u16 num, unsigned short *sectorSize, u08 *status) {
+u16 loadAtxSector(u16 num, unsigned short *sectorSize, u08 *status) {
     struct atxTrackHeader *trackHeader;
     struct atxSectorListHeader *slHeader;
     struct atxSectorHeader *sectorHeader;
@@ -144,9 +180,10 @@
     u16 headPosition = getCurrentHeadPosition();
 
     // read the track header
-    u32 currentFileOffset = gTrackInfo[drive][tgtTrackNumber - 1].offset;
+    u32 currentFileOffset = gTrackInfo[tgtTrackNumber - 1].offset;
     faccess_offset(FILE_ACCESS_READ, currentFileOffset, sizeof(struct atxTrackHeader));
     trackHeader = (struct atxTrackHeader *) atari_sector_buffer;
+    byteswapatxtrackheader(trackHeader);
     u16 sectorCount = trackHeader->sectorCount;
 
     // if there are no sectors in this track or the track number doesn't match, return error
@@ -158,6 +195,7 @@
     currentFileOffset += trackHeader->headerSize;
     faccess_offset(FILE_ACCESS_READ, currentFileOffset, sizeof(struct atxSectorListHeader));
     slHeader = (struct atxSectorListHeader *) atari_sector_buffer;
+    byteswapatxsectorlistheader(slHeader);
 
     // sector list header is variable length, so skip any extra header bytes that may be present
     currentFileOffset += slHeader->next - sectorCount * sizeof(struct atxSectorHeader);
@@ -167,6 +205,7 @@
     for (i=0; i < sectorCount; i++) {
         if (faccess_offset(FILE_ACCESS_READ, currentFileOffset, sizeof(struct atxSectorHeader))) {
             sectorHeader = (struct atxSectorHeader *) atari_sector_buffer;
+	    byteswapatxsectorheader(sectorHeader);
             // if the sector number matches the one we're looking for...
             if (sectorHeader->number == tgtSectorNumber) {
                 // check if it's the next sector that the head would encounter angularly...
@@ -200,10 +239,11 @@
     // if an extended data record exists for this track, iterate through all track chunks to search
     // for those records (note that we stop looking for chunks when we hit the 8-byte terminator; length == 0)
     if (extendedDataRecords > 0) {
-        currentFileOffset = gTrackInfo[drive][tgtTrackNumber - 1].offset + trackHeader->headerSize;
+        currentFileOffset = gTrackInfo[tgtTrackNumber - 1].offset + trackHeader->headerSize;
         do {
             faccess_offset(FILE_ACCESS_READ, currentFileOffset, sizeof(struct atxTrackChunk));
             extSectorData = (struct atxTrackChunk *) atari_sector_buffer;
+            byteswapatxtrackchunk(extSectorData);
             if (extSectorData->size > 0) {
                 // if the target sector has a weak data flag, grab the start weak offset within the sector data
                 if (extSectorData->sectorIndex == tgtSectorIndex && extSectorData->type == 0x10) {
@@ -218,7 +258,7 @@
     *sectorSize = gBytesPerSector;
 
     // read the data (re-using tgtSectorIndex variable here to reduce stack consumption)
-    tgtSectorIndex = tgtSectorOffset ? (u16) faccess_offset(FILE_ACCESS_READ, gTrackInfo[drive][tgtTrackNumber - 1].offset + tgtSectorOffset, gBytesPerSector) : (u16) 0;
+    tgtSectorIndex = tgtSectorOffset ? (u16) faccess_offset(FILE_ACCESS_READ, gTrackInfo[tgtTrackNumber - 1].offset + tgtSectorOffset, gBytesPerSector) : (u16) 0;
     tgtSectorIndex = hasError ? (u16) 0 : tgtSectorIndex;
 
     // if a weak offset is defined, randomize the appropriate data
@@ -257,22 +297,3 @@
     return ret;
 }
 
-void waitForAngularPosition(u16 pos) {
-    // if the position is less than the current timer, we need to wait for a rollover 
-    // to occur
-    if (pos < TCNT1 / 2) {
-        TIFR1 |= _BV(OCF1A);
-        while (!(TIFR1 & _BV(OCF1A)));
-    }
-    // wait for the timer to reach the target position
-    while (TCNT1 / 2 < pos);
-}
-
-u16 getCurrentHeadPosition() {
-    // TCNT1 is a variable driven by an Atmel timer that ticks every 4 microseconds. A full 
-    // rotation of the disk is represented in an ATX file by an angular positional value 
-    // between 1-26042 (or 8 microseconds based on 288 rpms). So, TCNT1 / 2 always gives the 
-    // current angular position of the drive head on the track any given time assuming the 
-    // disk is spinning continously.
-    return TCNT1 / 2;
-}
