From 57bf045cc84de2f12dbea071fe8e9cba89f9fe31 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sat, 22 Feb 2020 12:06:40 +0000 Subject: [PATCH] some big endian improvents and drive_fat fixes. (jmarsh) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4330 --- include/mem.h | 43 +++++++++++++++++++------- src/dos/drive_fat.cpp | 70 ++++++++++++++++++++++++++----------------- 2 files changed, 75 insertions(+), 38 deletions(-) diff --git a/include/mem.h b/include/mem.h index 99b082e8..7393b778 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]; } + +static INLINE void host_writeb(HostPt off,Bit8u val) { + off[0]=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 *(Bit8u *)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) { - *(Bit8u *)(off)=val; -} static INLINE void host_writew(HostPt off,Bit16u val) { *(Bit16u *)(off)=val; } @@ -118,6 +131,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 e75b47c1..d6517039 100644 --- a/src/dos/drive_fat.cpp +++ b/src/dos/drive_fat.cpp @@ -223,20 +223,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; } @@ -333,7 +325,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 { @@ -341,10 +333,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; } @@ -380,7 +372,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; @@ -392,14 +384,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 || @@ -1039,6 +1043,18 @@ char* trimString(char* str) { return removeTrailingSpaces(removeLeadingSpaces(str)); } +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 */ @@ -1110,11 +1126,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; } @@ -1189,7 +1205,7 @@ bool fatDrive::directoryBrowse(Bit32u dirClustNumber, direntry *useEntry, Bit32s --entNum; } - memcpy(useEntry, §buf[entryoffset],sizeof(direntry)); + copyDirEntry(§buf[entryoffset], useEntry); return true; } @@ -1223,9 +1239,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; } @@ -1264,7 +1280,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; }