diff --git a/include/mem.h b/include/mem.h index 5f1a5c54..da130bb8 100644 --- a/include/mem.h +++ b/include/mem.h @@ -57,20 +57,39 @@ MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); Working on big or little endian machines */ -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - static INLINE Bit8u host_readb(HostPt off) { - return off[0]; + return *off; } + +static INLINE void host_writeb(HostPt off,Bit8u val) { + *off = val; +} + +// use __builtin_bswap* for gcc >= 4.3 +#if defined(WORDS_BIGENDIAN) && defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + +static INLINE Bit16u host_readw(HostPt off) { + return __builtin_bswap16(*(Bit16u *)off); +} +static INLINE Bit32u host_readd(HostPt off) { + return __builtin_bswap32(*(Bit32u *)off); +} +static INLINE void host_writew(HostPt off, Bit16u val) { + *(Bit16u *)off = __builtin_bswap16(val); +} +static INLINE void host_writed(HostPt off, Bit32u val) { + *(Bit32u *)off = __builtin_bswap32(val); +} + +#elif defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) + static INLINE Bit16u host_readw(HostPt off) { return off[0] | (off[1] << 8); } static INLINE Bit32u host_readd(HostPt off) { return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); } -static INLINE void host_writeb(HostPt off,Bit8u val) { - off[0]=val; -} static INLINE void host_writew(HostPt off,Bit16u val) { off[0]=(Bit8u)(val); off[1]=(Bit8u)(val >> 8); @@ -84,18 +103,12 @@ static INLINE void host_writed(HostPt off,Bit32u val) { #else -static INLINE Bit8u host_readb(HostPt off) { - return *off; -} static INLINE Bit16u host_readw(HostPt off) { return *(Bit16u *)off; } static INLINE Bit32u host_readd(HostPt off) { return *(Bit32u *)off; } -static INLINE void host_writeb(HostPt off,Bit8u val) { - *off = val; -} static INLINE void host_writew(HostPt off,Bit16u val) { *(Bit16u *)(off)=val; } @@ -156,6 +169,14 @@ static INLINE void var_write(Bit32u * var, Bit32u val) { host_writed((HostPt)var, val); } +static INLINE Bit16u var_read(Bit16u * var) { + return host_readw((HostPt)var); +} + +static INLINE Bit32u var_read(Bit32u * var) { + return host_readd((HostPt)var); +} + /* The Folowing six functions are slower but they recognize the paged memory system */ Bit8u mem_readb(PhysPt pt); diff --git a/src/dos/drive_fat.cpp b/src/dos/drive_fat.cpp index 026e4e17..51a04a21 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -229,20 +229,12 @@ bool fatFile::Write(Bit8u * data, Bit16u *size) { if(loadedSector) myDrive->writeSector(currentSector, sectorBuffer); currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); - if(currentSector == 0) { - /* EOC reached before EOF - try to increase file allocation */ - myDrive->appendCluster(firstCluster); - /* Try getting sector again */ - currentSector = myDrive->getAbsoluteSectFromBytePos(firstCluster, seekpos); - if(currentSector == 0) { - /* No can do. lets give up and go home. We must be out of room */ - loadedSector = false; - goto finalizeWrite; - } + if(currentSector == 0) loadedSector = false; + else { + curSectOff = 0; + myDrive->readSector(currentSector, sectorBuffer); + loadedSector = true; } - curSectOff = 0; - myDrive->readSector(currentSector, sectorBuffer); - loadedSector = true; } --sizedec; } @@ -339,7 +331,7 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { switch(fattype) { case FAT12: - clustValue = *((Bit16u *)&fatSectBuffer[fatentoff]); + clustValue = var_read((Bit16u *)&fatSectBuffer[fatentoff]); if(clustNum & 0x1) { clustValue >>= 4; } else { @@ -347,10 +339,10 @@ Bit32u fatDrive::getClusterValue(Bit32u clustNum) { } break; case FAT16: - clustValue = *((Bit16u *)&fatSectBuffer[fatentoff]); + clustValue = var_read((Bit16u *)&fatSectBuffer[fatentoff]); break; case FAT32: - clustValue = *((Bit32u *)&fatSectBuffer[fatentoff]); + clustValue = var_read((Bit32u *)&fatSectBuffer[fatentoff]); break; } @@ -386,7 +378,7 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { switch(fattype) { case FAT12: { - Bit16u tmpValue = *((Bit16u *)&fatSectBuffer[fatentoff]); + Bit16u tmpValue = var_read((Bit16u *)&fatSectBuffer[fatentoff]); if(clustNum & 0x1) { clustValue &= 0xfff; clustValue <<= 4; @@ -398,14 +390,14 @@ void fatDrive::setClusterValue(Bit32u clustNum, Bit32u clustValue) { tmpValue &= 0xf000; tmpValue |= (Bit16u)clustValue; } - *((Bit16u *)&fatSectBuffer[fatentoff]) = tmpValue; + var_write((Bit16u *)&fatSectBuffer[fatentoff], tmpValue); break; } case FAT16: - *((Bit16u *)&fatSectBuffer[fatentoff]) = (Bit16u)clustValue; + var_write((Bit16u *)&fatSectBuffer[fatentoff], (Bit16u)clustValue); break; case FAT32: - *((Bit32u *)&fatSectBuffer[fatentoff]) = clustValue; + var_write((Bit32u *)&fatSectBuffer[fatentoff], clustValue); break; } for(int fc=0;fcRead_AbsoluteSector(0+partSectOff,&bootbuffer); + bootbuffer.bytespersector = var_read(&bootbuffer.bytespersector); + bootbuffer.reservedsectors = var_read(&bootbuffer.reservedsectors); + bootbuffer.rootdirentries = var_read(&bootbuffer.rootdirentries); + bootbuffer.totalsectorcount = var_read(&bootbuffer.totalsectorcount); + bootbuffer.sectorsperfat = var_read(&bootbuffer.sectorsperfat); + bootbuffer.sectorspertrack = var_read(&bootbuffer.sectorspertrack); + bootbuffer.headcount = var_read(&bootbuffer.headcount); + bootbuffer.hiddensectorcount = var_read(&bootbuffer.hiddensectorcount); + bootbuffer.totalsecdword = var_read(&bootbuffer.totalsecdword); + if (!is_hdd) { /* Identify floppy format */ if ((bootbuffer.nearjmp[0] == 0x69 || bootbuffer.nearjmp[0] == 0xe9 || @@ -1093,6 +1097,18 @@ char* trimString(char* str, const size_t max_len) { return removeTrailingSpaces(removeLeadingSpaces(str, max_len), max_len); } +static void copyDirEntry(const direntry *src, direntry *dst) { + memcpy(dst, src, 14); // single byte fields + var_write(&dst->crtTime, src->crtTime); + var_write(&dst->crtDate, src->crtDate); + var_write(&dst->accessDate, src->accessDate); + var_write(&dst->hiFirstClust, src->hiFirstClust); + var_write(&dst->modTime, src->modTime); + var_write(&dst->modDate, src->modDate); + var_write(&dst->loFirstClust, src->loFirstClust); + var_write(&dst->entrysize, src->entrysize); +} + bool fatDrive::FindNextInternal(Bit32u dirClustNumber, DOS_DTA &dta, direntry *foundEntry) { direntry sectbuf[16]; /* 16 directory entries per sector */ Bit32u logentsector; /* Logical entry sector */ @@ -1164,11 +1180,11 @@ nextfile: /* Compare name to search pattern */ if(!WildFileCmp(find_name,srch_pattern)) goto nextfile; - //dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].crtDate, sectbuf[entryoffset].crtTime, sectbuf[entryoffset].attrib); + copyDirEntry(§buf[entryoffset], foundEntry); - dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].modDate, sectbuf[entryoffset].modTime, sectbuf[entryoffset].attrib); + //dta.SetResult(find_name, foundEntry->entrysize, foundEntry->crtDate, foundEntry->crtTime, foundEntry->attrib); - memcpy(foundEntry, §buf[entryoffset], sizeof(direntry)); + dta.SetResult(find_name, foundEntry->entrysize, foundEntry->modDate, foundEntry->modTime, foundEntry->attrib); return true; } @@ -1243,7 +1259,7 @@ bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s --entNum; } - memcpy(useEntry, §buf[entryoffset],sizeof(direntry)); + copyDirEntry(§buf[entryoffset], useEntry); return true; } @@ -1277,9 +1293,9 @@ bool fatDrive::directoryChange(Bit32u dirClustNumber, direntry *useEntry, Bit32s --entNum; } if(tmpsector != 0) { - memcpy(§buf[entryoffset], useEntry, sizeof(direntry)); + copyDirEntry(useEntry, §buf[entryoffset]); writeSector(tmpsector, sectbuf); - return true; + return true; } else { return false; } @@ -1318,7 +1334,7 @@ bool fatDrive::addDirectoryEntry(Bit32u dirClustNumber, direntry useEntry) { /* Deleted file entry or end of directory list */ if ((sectbuf[entryoffset].entryname[0] == 0xe5) || (sectbuf[entryoffset].entryname[0] == 0x00)) { - sectbuf[entryoffset] = useEntry; + copyDirEntry(&useEntry, §buf[entryoffset]); writeSector(tmpsector,sectbuf); break; }