Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions src/asmexception.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ class AsmException_FileError : public AsmException
public:

explicit AsmException_FileError( const std::string& filename )
: m_filename( filename )
: m_filename( filename ),
m_detail()
{
}

AsmException_FileError( const std::string& filename, const std::string& detail )
: m_filename( filename ),
m_detail( detail )
{
}

Expand All @@ -68,12 +75,17 @@ class AsmException_FileError : public AsmException

virtual const char* Message() const
{
if ( !m_detail.empty() )
{
return m_detail.c_str();
}
return "Unspecified file error.";
}

protected:

std::string m_filename;
std::string m_detail;
};


Expand All @@ -84,9 +96,19 @@ public: \
explicit AsmException_FileError_##a( const std::string& filename ) \
: AsmException_FileError( filename ) {} \
\
AsmException_FileError_##a( const std::string& filename, const std::string& detail ) \
: AsmException_FileError( filename, detail ) {} \
\
virtual ~AsmException_FileError_##a() {} \
\
virtual const char* Message() const { return msg; } \
virtual const char* Message() const \
{ \
if ( !m_detail.empty() ) \
{ \
return m_detail.c_str(); \
} \
return msg; \
} \
}


Expand Down
71 changes: 69 additions & 2 deletions src/discimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,55 @@
using namespace std;


/*************************************************************************************************/
/**
BuildInputFileErrorMessage()

Helper function to build detailed diagnostic message for input file read failures.
Examines stream state to provide actionable information about what went wrong.

@param description What was being read (e.g., "catalogue", "sector 5")
@param expectedBytes Number of bytes attempted to read
@param inputStream The input stream that failed
@return A detailed error message string
*/
/*************************************************************************************************/
static string BuildInputFileErrorMessage(
const string& description,
size_t expectedBytes,
ifstream& inputStream )
{
ostringstream msg;

streamsize actualBytes = inputStream.gcount();
bool hitEof = inputStream.eof();
streampos currentPos = inputStream.tellg();

msg << "Problem reading from disc image.";

// Add specific context about what was being read
msg << " Failed to read " << description;
msg << ": attempted " << expectedBytes << " bytes";
msg << ", got " << actualBytes;

// Add EOF information if applicable
if ( hitEof )
{
msg << " (unexpected end of file)";
}

// Add current position if available
if ( currentPos != static_cast<streampos>(-1) )
{
msg << ". Position: " << currentPos;
}

msg << ".";

return msg.str();
}


/*************************************************************************************************/
/**
DiscImage::DiscImage()
Expand Down Expand Up @@ -61,6 +110,7 @@ DiscImage::DiscImage( const char* pOutput, const char* pInput )
throw AsmException_FileError_OpenDiscSource( pInput );
}

// Read the catalogue
if ( !m_inputFile.read( reinterpret_cast< char* >( m_aCatalog ), 0x200 ) )
{
throw AsmException_FileError_ReadDiscSource( pInput );
Expand Down Expand Up @@ -94,13 +144,30 @@ DiscImage::DiscImage( const char* pOutput, const char* pInput )
assert( length >= endSectorAddr * 0x100 );
#endif

// Write the catalogue (sectors 0-1) directly from the in-memory buffer.
// This avoids redundant I/O and is consistent with the destructor
// which also writes the catalogue from m_aCatalog.

if ( !m_outputFile.write( reinterpret_cast< char* >( m_aCatalog ), 0x200 ) )
{
throw AsmException_FileError_WriteDiscDest( pOutput );
}

// Copy the remaining file data sectors (2 onwards) from the input disc image.
// The input file pointer is correctly positioned at offset 0x200 (start of sector 2)
// after the initial catalogue read

char sector[ 0x100 ];

for ( int sect = 0; sect < endSectorAddr; sect++ )
for ( int sect = 2; sect < endSectorAddr; sect++ )
{
if ( !m_inputFile.read( sector, 0x100 ) )
{
throw AsmException_FileError_ReadDiscSource( pInput );
// Build detailed diagnostic message
ostringstream desc;
desc << "sector " << sect;
string errorMsg = BuildInputFileErrorMessage( desc.str(), 0x100, m_inputFile );
throw AsmException_FileError_ReadDiscSource( pInput, errorMsg );
}

if ( !m_outputFile.write( sector, 0x100 ) )
Expand Down
Binary file added test/3-directives/template/template.ssd
Binary file not shown.
11 changes: 11 additions & 0 deletions test/3-directives/template/usetemplateboot.6502
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
\ beebasm -di template.ssd -do test.ssd

\ Test using -di option with a template disc image that has a !BOOT file.

ORG &8000

.start
RTS
.end

SAVE "tester", start, end
Binary file not shown.
Loading