LOAD: do not mistake a line number for the end of file marker - #6
Open
stefanobaldo wants to merge 1 commit into
Open
LOAD: do not mistake a line number for the end of file marker#6stefanobaldo wants to merge 1 commit into
stefanobaldo wants to merge 1 commit into
Conversation
LOAD tested every byte it copied for 1ah, including the two bytes of each line number, so a line whose number's low byte is 1ah ended the load and everything after it was lost without an error. Line numbers congruent to 26 modulo 256 are affected: 26, 282, 538, 794, 1050, and so on. This is issue dimitrit#5. The copy loop no longer tests for the marker. It cannot usefully do so: at the moment it sees 1ah it has no idea whether that byte is a line number's low half or the terminator, and telling those apart needs the previous line number, which the loop cannot carry because the BDOS call between records destroys the registers. The end of the program is found afterwards instead, by walking the lines that were read. Only at a line's first byte can 1ah be the marker, and even there it is only the marker when the two bytes do not read as a line number greater than the one before it: line numbers ascend, and the NUL padding that follows a saved program's marker does not. One residual remains, and it is in the format rather than in this code: if the bytes after the marker happen to read as an ascending line number followed by a carriage return, the walk takes them for a line. A file saved by Tasty Basic pads with NUL and cannot do that. Measured before and after, on the CP/M build, with these files: file before after expected 100 / 1050 / 1100, as issue dimitrit#5 1 3 3 10 / 26 / 30, the other degenerate 1 3 3 examples/TICTAC.BAS, assembled 94 117 117 examples/tictac.tba, as shipped 94 117 117 a line 1050 inside the last record 13 15 15 a program with no such number 3 3 3 The shipped tictac.tba is worth a word: the file is complete, all 117 lines of it. It only ever loaded as 94, which is why the game fails at line 1020 on a GOTO 1050 that was never brought into memory. Nothing needs regenerating. The ROMWBW build is unaffected and assembles byte for byte identical; this file is only included for CP/M.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #5.
The change
LOADtested every byte it copied for1ah, including the two bytes of eachline number, so a line whose number's low byte is
1ahended the load andeverything after it was lost with no error reported.
The copy loop no longer tests for the marker. It cannot usefully do so: at the
moment it sees
1ahit has no idea whether that byte is a line number's lowhalf or the terminator, and telling those apart needs the previous line
number, which the loop cannot carry — the BDOS call between records destroys
the registers.
The end of the program is found afterwards, by walking the lines that were
read. Only at a line's first byte can
1ahbe the marker, and even there itis only the marker when the two bytes do not read as a line number greater
than the one before it: line numbers ascend, and the NUL padding that follows
a saved program's marker does not.
+50 −2insrc/cpmio.asm, and the two deleted lines are thecp 1ahandits
jr. Nothing else was restructured.Measured
Before and after, on the CP/M build, counting the lines a
LISTshows aftera
LOAD:100/1050/1100, the case in #510/26/30, the other degenerate numberexamples/TICTAC.BAS, assembled to.TBAexamples/tictac.tba, exactly as shipped1050placed inside the file's last recordexamples/tictac.tbais worth a word: the file is complete, all 117 lines ofit. It only ever loaded as 94, which is why the game fails at line 1020 with
HOW?— itsGOTO 1050targets a line that was never brought into memory.With this change it loads whole and the game plays. Nothing needs regenerating.
The ROMWBW build assembles byte for byte identical, as it must: this file is
only included for CP/M.
The residual
One case remains, and it is in the format rather than in this code: if the
bytes after the marker happen to read as an ascending line number followed by
a carriage return, the walk takes them for a line. A file saved by Tasty Basic
pads with NUL and cannot do that. Saying so rather than claiming the hole is
closed.
How it was tested
Under an emulated Z80 with a host-side BDOS, assembled with uz80as 2.02 using
the version string the Makefile passes. The counts above come from running the
patched and unpatched binaries over the same files.