Skip to content

Conversation

@rob-smallshire
Copy link

The -di option (disc image template) fails with the error "Problem reading from disc image" when attempting to use an existing disc image as a template for a new disc image,

$ beebasm -v -i rom.asm -di template.ssd -do rom.ssd
Error: template.ssd: Problem reading from disc image.

The commits of this PR add a failing test to reproduce the issue, improve the diagnostics to shed light on the problem, and implement a fix.

Cause: In discimage.cpp, the constructor reads the 512-byte catalogue into memory, advancing the file pointer to position 0x200. The subsequent sector-copying loop then attempts to read sectors from the current file position instead of seeking back to the start of the file. This causes reads to fail when the loop tries to read past the end of the file.

The fix writes the catalogue directly from the in-memory buffer (to which it was already read) and only reads the remaining data sectors from the input file. This:

  • Eliminates the bug by avoiding the need to re-read the catalogue (an alternative shorter fix is possible by seeking back to the beginning of the file, but that's inconsistent with what the code does elsewhere)
  • Avoids a redundant read
  • Makes the code consistent with how the destructor handles the catalogue (also writes from the buffer)
  • Establishes m_aCatalog as the single source of truth for the catalogue

I took a few liberties with improving the capabilities of the error reporting, but I felt that,

Error: template.ssd: Problem reading from disc image. Failed to read sector 1: attempted 256 bytes, got 0 (unexpected end of file).

was a sufficiently worthwhile improvement over,

Error: template.ssd: Problem reading from disc image.

so as to be worthwhile. Similar improvements to error reporting elsewhere are now a bit easier too.

  The catalogue was being read into memory at position 0x200, then the
  sector copy loop tried to read from the current file position instead
  of seeking back to the start. This caused reads to fail or copy the
  wrong data.

  Now writes the catalogue directly from the in-memory buffer and only
  reads the remaining data sectors from the file, eliminating the bug
  and redundant I/O.

Add expected output for template disc image test

This completes the test by adding the gold file generated after
the fix was applied.
@mungre
Copy link
Collaborator

mungre commented Dec 1, 2025

Thank you, I'll have a proper look tomorrow.

The tests used to run automatically but I had to click a button in github to allow them to run. In case you don't have access to the results, the usetemplateboot.6502 test is failing inconsistently. An example failure:

======================================================================
2025-12-01T23:38:10.3411499Z TEST: ./3-directives/template/usetemplateboot.6502
2025-12-01T23:38:10.3411595Z ======================================================================
2025-12-01T23:38:10.3411997Z ['/home/runner/work/beebasm/beebasm/beebasm', '-v', '-di', 'template.ssd', '-do', 'test.ssd', '-do', 'test.ssd', '-i', 'usetemplateboot.6502']
2025-12-01T23:38:10.3412059Z .start
2025-12-01T23:38:10.3412137Z      8000   60         RTS
2025-12-01T23:38:10.3412203Z .end
2025-12-01T23:38:10.3412418Z Saving file 'tester'
2025-12-01T23:38:10.3412523Z Processed file 'usetemplateboot.6502' ok
2025-12-01T23:38:10.3412669Z Comparing output ssd to usetemplateboot.gold.ssd failed
2025-12-01T23:38:10.3412834Z FAILURE: ssd does not match gold ssd: usetemplateboot.gold.ssd

@rob-smallshire
Copy link
Author

Thanks for letting me know. I can take a look at the failures later this week.

@mungre
Copy link
Collaborator

mungre commented Dec 2, 2025

I know this feature does get used so I was surprised it was broken. It turns out I broke it last year but we haven't released a version with that change yet. I added the NDEBUG flag to the makefile build (among other changes) to improve the performance. I also carelessly made this seeking code debug-only thinking it was only used for the assert, but that broke the feature.

Your fix works in release builds but fails in debug builds because m_inputFile.seekg( 0, ios::beg ); seeks to the start of the file. Changing that 0 to 0x200 should fix it.

@mungre
Copy link
Collaborator

mungre commented Dec 2, 2025

Come to think of it, if you can be bothered you could remove the #ifndef NDEBUG that I foolishly added and turn the assert into a proper error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants