// 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 "pub.def" #include "jintypes.h" int g_iBlkEnd = 0; int g_iBlkStart = 0; int g_iBlkLength = 0; int g_iBlkBase = 0; char szStart[ MAX_PATH ]; char szEnd[ MAX_PATH ]; char szLength[ MAX_PATH ]; BOOL g_bStartUsed = FALSE; BOOL g_bEndUsed = FALSE; BOOL g_bLenUsed = FALSE; int g_bOutputIsAtari = FALSE; int g_bUseBase = FALSE; #define SHEADER PRG_NAME " v" PRG_VERSION " (c) " PRG_COPYRIGHT " " PRG_AUTHOR "\n" #define HEADER SHEADER \ PRG_DESC "\n" \ " Latest version can be found at " PRG_URL "\n" \ " Published under GPL. See GPL.TXT.\n\n" #define USAGE HEADER "Usage: " PRG_NAME " " PRG_USAGE #include "switches.cpp" int ToNum( char*, int ); int main( int argc, char *argv[] ) { setbuf( stdout, NULL ); setbuf( stderr, NULL ); if ( !SWITCHES_Init( &argc, argv ) ) return 1; if ( argc < 2 ) { SWFN_HELP( USAGE ); return 1; } fprintf( stderr, SHEADER ); char* szInfile = argv[ 1 ]; char szOutfile[ MAX_PATH ]; if ( argc >= 3 ) { strcpy( szOutfile, argv[ 2 ] ); } else { strcpy( szOutfile, "prg.axe" ); } int hIn = open( szInfile, O_RDONLY | O_BINARY ); if ( hIn == -1 ) { fprintf( stderr, "Can't open infile '%s'!\n", szInfile ); return -1; } if( g_bStartUsed ) { g_iBlkStart = ToNum( szStart, 1 ); } if( g_bEndUsed ) { g_iBlkEnd = ToNum( szEnd, 1 ); } if( g_bLenUsed ) { g_iBlkLength = ToNum( szLength, 0 ); } LONG lLen = lseek( hIn, 0, SEEK_END ); lseek( hIn, 0, SEEK_SET ); if( g_bEndUsed && g_iBlkEnd < 1 ) { g_iBlkEnd = lLen - 1 + g_iBlkEnd; } if( g_bStartUsed ) { if ( g_bEndUsed ) { g_iBlkLength = g_iBlkEnd - g_iBlkStart + 1; } else { //START & ? if ( g_bLenUsed ) { //start & length g_iBlkEnd = g_iBlkStart + g_iBlkLength - 1; } else { //start & nothing g_iBlkEnd = lLen - 1; g_iBlkLength = g_iBlkEnd - g_iBlkStart + 1; } } } else if( g_bEndUsed ) { if( g_bLenUsed ) { //end & length g_iBlkStart = g_iBlkEnd - g_iBlkLength + 1; } else { //end only g_iBlkStart = 0; g_iBlkLength = g_iBlkEnd - g_iBlkStart + 1; } } else { if( g_bLenUsed ) { //length only g_iBlkStart = 0; g_iBlkEnd = g_iBlkStart + g_iBlkLength - 1; } else { //nothing g_iBlkStart = 0; g_iBlkLength = lLen; g_iBlkEnd = g_iBlkStart + g_iBlkLength - 1; } } if( ( g_iBlkStart < 0 ) || ( g_iBlkStart >= lLen ) ) { fprintf( stderr, "Invalid start ptr!\n" ); close( hIn ); return -1; } if( ( g_iBlkEnd < 0 ) || ( g_iBlkEnd >= lLen ) || ( g_iBlkEnd < g_iBlkStart ) ) { fprintf( stderr, "Invalid end ptr!\n" ); close( hIn ); return -1; } int iBlkStartM = g_iBlkStart; int iBlkEndM = g_iBlkEnd; if( g_bUseBase ) { iBlkStartM = g_iBlkBase; iBlkEndM = g_iBlkBase + g_iBlkLength - 1; } if ( ( ( iBlkEndM >= 0x10000 ) || ( iBlkStartM >= 0x10000 ) ) && g_bOutputIsAtari ) { fprintf( stderr, "End goes past end of RAM in real Atari!\n" ); close( hIn ); return -1; } int hOut = open( szOutfile, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, 0666 ); if ( hOut == -1 ) { fprintf( stderr, "Can't open outfile '%s'!\n", szOutfile ); close( hIn ); return -1; } #define BUFLEN 0x10000 BYTE* pbtPtr = new BYTE [ BUFLEN ]; lseek( hIn, g_iBlkStart, SEEK_SET ); if ( g_bOutputIsAtari ) { WORD wStart = iBlkStartM; WORD wEnd = iBlkEndM; BYTE btPom = 0xFF; write( hOut, &btPom, 1 ); write( hOut, &btPom, 1 ); btPom = wStart & 0xFF; write( hOut, &btPom, 1 ); btPom = wStart >> 8; write( hOut, &btPom, 1 ); btPom = wEnd & 0xFF; write( hOut, &btPom, 1 ); btPom = wEnd >> 8; write( hOut, &btPom, 1 ); } int iLeft = g_iBlkLength; while( iLeft ) { int iReadNow = iLeft > BUFLEN ? BUFLEN : iLeft; read( hIn, pbtPtr, iReadNow ); write( hOut, pbtPtr, iReadNow ); iLeft -= iReadNow; } close( hOut ); close( hIn ); printf( "Done!\n" ); return 0; } int ToNum( char* szString, int iOffs ) { BOOL bSec = FALSE; if( *szString == 's' ) { bSec = TRUE; szString++; } int iNum; sscanf( szString, "%X", &iNum ); if( bSec ) { if( iNum < iOffs ) { printf( "Incorrect sector number %s\n", szString ); return -1; } iNum -= iOffs; iNum *= 0x80; if( iOffs ) { //begin & end iNum += 0x10; } //whole code assumes SD ATR file!!! } return iNum; }