The BINENTRY bug

If you downloaded the previous version of BINENTRY (the one that was available until 18-Jul-1999), and used it to enter COMM4.BIN, you probably found that COMM4 had troubles, either hanging or going berserk ten seconds after downloading the last byte of data. The actual mistake is not in COMM4 though, it is in BINENTRY. If you are not sure which version you have, look at program line "2". The buggy initial version does not even have line number 2, but later versions have a comment there telling the version number.

What went wrong?

How can I fix it?


What went wrong?

The bug is an off-by-one error in the place that puts data into memory. So instead of putting COMM4 into $3000 through $30B7, it stored it in addresses $3001 through $30B8.

That by itself is not so terrible, because within some limits, COMM4 is relocatable. It can work okay at those addresses. But there are two problems that come with that.

First, after putting the data into the wrong memory locations, BINENTRY proceeds to save data from the correct range of addresses, $3000 through $30B7, into the disk file. So it gets one scrap byte at address $3000: whatever byte happened to be sitting there before you ran BINENTRY. From our point of view, that is a random number. It also does not save the last byte of the program, which was put into address $30B8 because of the bug. So if you load COMM4 from the saved disk file, that last byte is not there.

That last byte is pretty important. It is the "return from subroutine" instruction that ends the program and returns control to the BASIC interpreter. Without that, the computer finishes downloading but then goes haywire, executing whatever bytes are sitting in the memory area following the program as if they were instructions. Most often it just locks up then, but it could do almost anything.

The other problem is similar. The program that runs COMM4 expects it to start at address $3000. So it starts executing instructions there, and the machine executes that scrap byte as if it were an instruction. Depending on the value of that byte, a number of things can happen, but the most common case is that the first few instructions of COMM4 are not executed properly, and then it gets back on track and runs the rest of the program. Since only the first few instructions are messed up by this, the program can actually run to completion like this. But it is dangerous, because those first few garbled instructions may have changed the values of a few bytes in other places, so the BASIC interpreter itself may have problems afterward. It could hang up unexpectedly, write random trash all over your disk, corrupt programs you load in the future - almost anything is possible.

Neither of these problems showed up in my tests at home because I was Stupid and Lucky. I was Stupid, because I ran COMM4 immediately after saving it with BINENTRY, instead of testing it the way any normal person would, by saving it, powering down, going to sleep for the night, and running it the next day. So in my test, the last byte was still sitting in memory, even though it did not get saved into the disk file. I was Lucky, because the random first byte that I got did not mess things up so terribly. So I ran it, and it successfully downloaded data at 9600 baud, with no visible problems.


How can I fix it?

If you did not delete the COMM4.BIN file, the solution is not so hard. We rename the bad version out of the way, reserve memory for it, re-load it into the right addresses, fill in the byte that did not get saved before, and re-save it:
   RENAME "COMM4.BIN" TO "COMM4.3K1"
   CLEAR 100,12286
   LOADM "COMM4.3K1",65535
   POKE &H30B7,&H39
   SAVEM "COMM4.BIN",&H3000,&H30B7,&H3000
If you deleted COMM4.BIN, but still have BINENTRY.BAS, you can fix it with a one-line patch. In fact, if you know how to edit lines, you can just insert a "-1" after the first "B" on line 190. If you re-type the whole line, be careful about the difference between the letter "Oh" and the digit "zero" here. The only two letter "Oh"s are in the word POKE at the beginning of the line, and in "O(B)" at the end of the line; the others are all zeros.
   LOAD "BINENTRY.BAS"
   3 REM BUGFIX 990720.1200
   190 POKE &H3000+(A-A0)+B-1,O(B)
   SAVE "BINENTRY.BAS"
After fixing this, you then have to re-run it and re-enter COMM4 again. Note that you will need the old version of the COMM4.BE input file to go with the old version of BINENTRY; the new BINENTRY wants the newer version of the input file.

Finally, if you deleted all of those files, you can download the new and improved BINENTRY, and the new COMM4 input file for that.

The new version of BINENTRY has several improvements, but two are important: First, it uses variable names that are easier to distinguish, so you won't go crazy trying to type it in. No more "O" (letter-oh) and "0" (zero) problems. Second, during execution it checks the entered line number, so you cannot accidentally skip a line or enter the lines out of order.

Unfortunately, it is slightly longer. But it should be easier to enter and easier to use, so the extra length is actually better. Also, It is incompatible with the previous version; it will reject every line of the old COMM4.BE file. So if you run this, make sure you feed it COMM4.BE3 as input. COMM4.BE3 is exactly the same size as COMM4.BE, but it includes the line count in each line's checksum, so that can be verified during entry. (COMM4.BE2 and COMM4.BE3 are exactly the same, because versions 2 and 3 of BINENTRY accept the same input.)


Back to my top-level CoCo page


13-Dec-99
yakowenk@csx.unxc.edu
(remove all "x"s to get a valid address)