aboutsummaryrefslogtreecommitdiff
path: root/jindroush/lib/cfs_robc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'jindroush/lib/cfs_robc.cpp')
-rw-r--r--jindroush/lib/cfs_robc.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/jindroush/lib/cfs_robc.cpp b/jindroush/lib/cfs_robc.cpp
new file mode 100644
index 0000000..089b4bc
--- /dev/null
+++ b/jindroush/lib/cfs_robc.cpp
@@ -0,0 +1,231 @@
+// 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_robc.h"
+#include "autil.h"
+#include "adsk_atr.h"
+
+#define ROBC_MAX_NAME 20
+
+CRobc::CRobc() : CFs()
+{
+ #ifdef _MEMORY_DUMP_
+ printf( "CRobc constructed: %08X\n", this );
+ #endif
+}
+
+CRobc::~CRobc()
+{
+ Dismount();
+ #ifdef _MEMORY_DUMP_
+ printf( "CRobc destructed: %08X\n", this );
+ #endif
+}
+
+BOOL CRobc::Mount( ADisk* pDisk )
+{
+ m_iFilesValid = 0;
+ m_iFilesInvalid = 0;
+ m_pDisk = pDisk;
+ m_pRoot = NULL;
+
+ if ( m_pDisk->GetSectorSize() != 0x80 )
+ {
+ sprintf( m_szLastError, "ROBC: Can't process DD disk!" );
+ return FALSE;
+ }
+
+ switch( m_pDisk->GetBootSectorCount() )
+ {
+ case 0x04:
+ break;
+
+ default:
+ {
+ sprintf( m_szLastError, "ROBC: Can't identify disk as a RobC menu!" );
+ return FALSE;
+ }
+ }
+
+ CRobcDirEntry* pPrev = NULL;
+
+ BYTE abtSec[ 0x180 ];
+
+ if ( !m_pDisk->ReadSectors( abtSec, 0x02, 3 ) )
+ {
+ sprintf( m_szLastError, "ROBC: Can't read directory because\n%s", m_pDisk->GetLastError() );
+ return FALSE;
+ }
+
+ BYTE* abtStartSecLo = abtSec + 0x77;
+ BYTE* abtStartSecHi = abtSec + 0x6E;
+ BYTE* pbtName = abtSec + 0xB9;
+
+ for( int i = 0; i < 10; i++ )
+ {
+ WORD wSec = *abtStartSecLo + ( *abtStartSecHi << 8 );
+
+ //printf( "%d) %04X\n", i, wSec );
+
+ if ( ! wSec )
+ continue;
+
+ BYTE abtLocSec[ 0x80 ];
+ BYTE btSecCount;
+
+ if( !m_pDisk->ReadSector( abtLocSec, wSec ) )
+ {
+ sprintf( m_szLastError, "ROBC: Can't read dir entry %d!", i );
+ return FALSE;
+ }
+
+ btSecCount = abtLocSec[ 1 ];
+
+ if ( ! btSecCount )
+ break;
+
+ CRobcDirEntry* pE = CreateEntry( btSecCount, wSec, pbtName + 2 );
+
+ if ( m_pRoot )
+ {
+ pPrev->m_pNext = pE;
+ pE->m_pPrev = pPrev;
+ pPrev = pE;
+ }
+ else
+ {
+ m_pRoot = pE;
+ pPrev = pE;
+ }
+
+ abtStartSecLo++;
+ abtStartSecHi++;
+ pbtName += ROBC_MAX_NAME;
+ }
+
+ return TRUE;
+}
+
+void CRobc::Dismount()
+{
+ DeleteList( m_pRoot );
+}
+
+CRobcDirEntry* CRobc::CreateEntry( BYTE btSecCount, WORD wStartSec, BYTE* btName )
+{
+ CRobcDirEntry* pE = new CRobcDirEntry();
+
+ if ( !pE )
+ return NULL;
+
+ pE->m_iStartSec = wStartSec;
+ pE->m_iSecCount = btSecCount;
+
+ sprintf( pE->m_szAscData, "%04X %02X", wStartSec, btSecCount );
+
+ char szTemp[ ROBC_MAX_NAME + 1 - 2 ];
+ memcpy( szTemp, btName, ROBC_MAX_NAME - 2 );
+ szTemp[ ROBC_MAX_NAME - 2 ] = '\0';
+
+ //printf( "%s\n", szTemp );
+
+ char* szT = szTemp;
+
+ while( *szT )
+ {
+ *szT &= 0x7F;
+ *szT -= 0x20;
+ szT++;
+ }
+
+ GuessBestFnameFromAtari( pE->m_szFname, szTemp, "atr" );
+
+ //printf( "%s\n", pE->m_szFname );
+
+ if ( ExportFile( NULL, pE ) )
+ m_iFilesValid++;
+ else
+ m_iFilesInvalid++;
+
+ return pE;
+}
+
+BOOL CRobc::ExportFile( char* szOutFile, CDirEntry* pDirE )
+{
+ int iSecCount = ((CRobcDirEntry*)pDirE) ->m_iSecCount;
+ int iStartSec = ((CRobcDirEntry*)pDirE) ->m_iStartSec;
+
+ BYTE abtBuff[ 0x80 ];
+
+ if ( ( iStartSec + iSecCount - 1 ) > m_pDisk->GetSectorCount() )
+ {
+ sprintf( m_szLastError, "ROBC: File '%s' goes past last sector!", szOutFile );
+ return FALSE;
+ }
+
+ m_pDisk->ReadSector( abtBuff, iStartSec );
+
+ if ( abtBuff[ 1 ] != iSecCount )
+ {
+ sprintf( m_szLastError, "ROBC: File '%s' Mismatched length (%d<>%d)!", szOutFile, abtBuff[ 1 ], iSecCount );
+ return FALSE;
+ }
+
+ if ( !szOutFile )
+ return TRUE;
+
+ CAtr newdisk;
+
+ DISK_GEOMETRY dg;
+
+ dg.iSides = 1;
+ dg.iTracks = 1;
+ dg.iSectorsPerTrack = iSecCount;
+ dg.iBytesPerSector = 0x80;
+
+ if ( !newdisk.Format( &dg ) )
+ {
+ sprintf( m_szLastError, "ROBC: File '%s' can't create because\n%s", szOutFile, newdisk.GetLastError() );
+ return FALSE;
+ }
+
+ int iCurrSec = 1;
+
+ while( iSecCount )
+ {
+ if( !m_pDisk->ReadSector( abtBuff, iStartSec++ ) )
+ {
+ sprintf( m_szLastError, "ROBC: File '%s' can't create because\n%s", szOutFile, m_pDisk->GetLastError() );
+ return FALSE;
+ }
+
+ if ( !newdisk.WriteSector( iCurrSec++, abtBuff ) )
+ {
+ sprintf( m_szLastError, "ROBC: File '%s' can't create because\n%s", szOutFile, newdisk.GetLastError() );
+ return FALSE;
+ }
+
+ iSecCount--;
+ }
+
+ if ( !newdisk.Save( szOutFile, FALSE ) )
+ {
+ sprintf( m_szLastError, "ROBC: File '%s' can't create because\n%s", szOutFile, newdisk.GetLastError() );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+