From a4cc3ad3504d634e379369862c9f9fd8eed379f3 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 16 May 2024 01:43:09 -0400 Subject: Add Jindrich Kubec's tools. --- jindroush/lib/cfs_dos3.cpp | 209 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 jindroush/lib/cfs_dos3.cpp (limited to 'jindroush/lib/cfs_dos3.cpp') diff --git a/jindroush/lib/cfs_dos3.cpp b/jindroush/lib/cfs_dos3.cpp new file mode 100644 index 0000000..2eca4b2 --- /dev/null +++ b/jindroush/lib/cfs_dos3.cpp @@ -0,0 +1,209 @@ +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "cfs_dos3.h" +#include "autil.h" + +#define ROOT_DIR 0x10 +#define FAT 0x18 + +CDos3::CDos3() : CFs() +{ + #ifdef _MEMORY_DUMP_ + printf( "CDos3 constructed: %08X\n", this ); + #endif +} + +CDos3::~CDos3() +{ + Dismount(); + #ifdef _MEMORY_DUMP_ + printf( "CDos3 destructed: %08X\n", this ); + #endif +} + +BOOL CDos3::Mount( ADisk* pDisk ) +{ + m_iFilesValid = 0; + m_iFilesInvalid = 0; + m_pDisk = pDisk; + m_pRoot = NULL; + + if ( m_pDisk->GetSectorSize() != 0x80 ) + { + sprintf( m_szLastError, "DOS3: Can't process DD disk!" ); + return FALSE; + } + + CDos3DirEntry* pPrev = NULL; + + DOS3_DIRENT dire; + + WORD wEntry = 1; + + if ( !pDisk->ReadSector( m_abtFat, FAT ) ) + { + sprintf( m_szLastError, "DOS3: Can't read FAT sector because\n%s", m_pDisk->GetLastError() ); + return FALSE; + } + + do + { + BYTE abtSec[ 0x100 ]; + + if ( !pDisk->ReadSector( abtSec, ROOT_DIR + ( wEntry / 8 ) ) ) + { + sprintf( m_szLastError, "DOS3: Can't read directory entry %04X because\n%s", wEntry, m_pDisk->GetLastError() ); + return FALSE; + } + + memcpy( &dire, abtSec + ( wEntry % 8) * sizeof( DOS3_DIRENT ), sizeof( DOS3_DIRENT ) ); + + if ( !dire.btFlags ) + break; + + CDos3DirEntry* pE = CreateEntry( &dire ); + + if ( pE && ! ( pE->m_dwFlags & DIRE_DELETED ) ) + { + if ( m_pRoot ) + { + pPrev->m_pNext = pE; + pE->m_pPrev = pPrev; + pPrev = pE; + } + else + { + m_pRoot = pE; + pPrev = pE; + } + + } + + wEntry++; + + } while( dire.btFlags ); + + return TRUE; +} + +void CDos3::Dismount() +{ + DeleteList( m_pRoot ); +} + +CDos3DirEntry* CDos3::CreateEntry( DOS3_DIRENT* pDire ) +{ + CDos3DirEntry* pE = new CDos3DirEntry(); + + if ( !pE ) + return NULL; + + if ( pDire->btFlags == 0x80 ) + { + pE->m_dwFlags |= DIRE_DELETED; + } + + ADos2MsDos( pE->m_szFname, pDire->acAtariName ); + + //sprintf( pE->m_szAscData, "%02X %02X %02X %04X", pDire->btSecStart, pDire->btSecCount, pDire->btFlags, pDire->wFileLen ); + sprintf( pE->m_szAscData, "%02X %04X", pDire->btFlags, pDire->wFileLen ); + + pE->m_btSecStart = pDire->btSecStart; + pE->m_btSecCount = pDire->btSecCount; + pE->m_btFlags = pDire->btFlags; + pE->m_wFileLen = pDire->wFileLen; + + if ( pE->m_dwFlags & DIRE_DELETED ) + { + } + else if ( ExportFile( NULL, pE ) ) + m_iFilesValid++; + else + m_iFilesInvalid++; + + return pE; +} + +BOOL CDos3::ExportFile( char* szOutFile, CDirEntry* pDirE ) +{ + int hOutfile = -1; + + if ( szOutFile ) + { + hOutfile = open( szOutFile, O_BINARY | O_CREAT | O_TRUNC | O_WRONLY, 0666 ); + + if ( -1 == hOutfile ) + { + sprintf( m_szLastError, "DOS3: Unable to create file '%s'!", szOutFile ); + return FALSE; + } + } + + BYTE abtBuff[ 0x80 * 8 ]; + + BYTE btSecCount = ((CDos3DirEntry*)pDirE) ->m_btSecCount; + BYTE btSector = ((CDos3DirEntry*)pDirE) ->m_btSecStart; + WORD wFileLen = ((CDos3DirEntry*)pDirE) ->m_wFileLen; + + while( btSecCount ) + { + WORD wToCopy = ( wFileLen < 0x400 ) ? wFileLen : 0x400; + + if ( !m_pDisk->ReadSectors( abtBuff, ( btSector * 8 ) + FAT + 1, 8 ) ) + { + { + sprintf( m_szLastError, "DOS3: Corrupted file '%s'\n%s\n", szOutFile, m_pDisk->GetLastError() ); + return FALSE; + } + } + + if ( -1 != hOutfile ) + write( hOutfile, abtBuff, wToCopy ); + + btSecCount--; + wFileLen -= wToCopy; + + btSector = m_abtFat[ btSector ]; + + if ( wToCopy == 0x400 ) + { + if ( btSector >= 0xFD ) + { + sprintf( m_szLastError, "DOS3: Corrupted file '%s' (unexpected EOF)", szOutFile ); + return FALSE; + } + + } + else + { + if ( btSector != 0xFD ) + { + sprintf( m_szLastError, "DOS3: Corrupted file '%s' (missed EOF) %02X", szOutFile, btSector ); + return FALSE; + } + + } + + + } + + + if ( -1 != hOutfile ) + close( hOutfile ); + + return TRUE; +} + -- cgit v1.2.3