A very classic topic is the ability to recover a BASIC program that has been killed by an unwanted NEW command. For instance, it may happen that someone issues a NEW command and then realizes that the program has never been saved.
Simons’ BASIC did provide a command to recover a deleted BASIC program: OLD. But, if you are using BASIC 2.0, such command is not provided. But, a simple machine language program will do the job.
What the command NEW really does
The command NEW does not erase the BASIC program in memory. It only sets to zero the first two bytes of the BASIC program. Those bytes normally contain the memory address of the second BASIC program line. If those are zero, the BASIC interpreter thinks that no program is in memory.
So, the NEW command fools the interpreter so that it THINKS no BASIC program is in memory. But actually, it’s still there.
To recover the program, we just need to restore the address of the second line of BASIC code, then we need to restore some BASIC pointers. Namely, the start of variables pointer (45, 46 decimal), the start of arrays pointer (47,48 decimal) and the end of arrays pointer (49,50 decimal).
So, we have to scan the “dead” program in memory, and we must find:
- the address of the BASIC program second line. Since each program line ends with a zero, this address is just the location right after the byte zero at the end of the first line;
- the end address of the BASIC program. Since a couple of zeroes are used to indicate the end of the program, and since the last program line ends with a zero like any other line, we must look for a sequence of three zero bytes in the BASIC program.
Here’s my simple solution to this very classic topic. My program is not short, nor optimized – but at least it seems to work. And it should be quite easy to understand for beginners or for people needing to dust off their knowledge in 6502 assembly language.
To better understand the code, it may be useful to note that the first four bytes of any BASIC line – as it is stored in memory – have a special meaning.
The first two bytes contain the address of the next BASIC line. The third and fourth bytes contain the line number (it is a 16 bit number, hence it asks for two bytes).
When looking for the end of the first program line, the routine must skip these four bytes.
To recover the apparently lost BASIC program, you only need to load this utility, then type SYS 49152. Your program will be back.
I like self-modifying code, but this time I didn’t use it. I have used indirect, indexed mode. By the way, instead of using the y register as an index, I have decided to directly increment both $fc and $fd zero page locations, used for the indirect address. It may seem odd, but I think it makes things much easier in this particular situation.
The UNNEW utility from Compute’s Gazette
Today I just wanted to try my hands at a problem that has been solved ages ago. And of course,the authors of Compute! did provide a solution at the very beginning of the Commodore 64 era.
I’ve found a program solving this problem in the issue N. 05 of Compute!’s Gazette (page 132).
I’ve typed in the program, tested it and compared with my own program. This program is much shorter than mine and works on the Commodore VIC 20 as well. But it was some sort of challenge to code my own solution without looking at the code from Compute!’s Gazette.
Here’s the program from the magazine that I’ve typed-in for you, and here’s the routine taken from the VICE machine language/assembly monitor.