Reverse engineering PDP-11 BASIC: Part 26
This short post describes TRAP 116 and the BASIC RUN, STOP, END and RANDOMIZE commands. For context and a list of other posts on this topic, see the PDP-11 BASIC reverse engineering project page.
TRAP 116 is used to reset the running state of a program. Here's the code:
001256 005067 CLR 13670 001262 005767 TST 13666 001266 001404 BEQ 1300 001270 016705 MOV 13666, R5 001274 005067 CLR 13666 001300 000207 RTS PC
Let's see how it works.
001256 005067 CLR 13670
The value at memory location 13670 is cleared. As mentioned in Part 24, when describing the INPUT, READ and RESTORE commands, this memory location is used to store the location in the program code up to which the DATA command values have been consumed by the running code.
By clearing this value, the code will begin consuming DATA command values from the beginning of the program again.
001262 005767 TST 13666 001266 001404 BEQ 1300
Next the value in memory location 13666 is tested. As described in Part 11 (see TRAP 112 in particular), when the program code is running, memory address 13666 is used to store the topmost address of the program code area. When the code is not running, R5 is used for this purpose and the value at address 13666 will be zero. TRAP 112 is the only place where a value other than zero is assigned to memory location 13666.
If the value at memory location 13666 it is equal to zero, control branches to 1300 to return immediately.
001270 016705 MOV 13666, R5 001274 005067 CLR 13666 001300 000207 RTS PC
Otherwise, the value from memory location 13666 is copied into R5 before the memory location is cleared. Control then returns to the calling code.
BASIC RUN command
The RUN command is used to begin execution of a program that has been typed in deferred mode. Here's the code:
004150 104516 TRAP 116 004152 005067 CLR 13660 004156 016701 MOV 13662, R1 004162 005201 INC R1 004164 012767 MOV #13507, 10050 004172 012767 MOV #1, 13664 004200 000167 JMP 3004
Let's see what happens:
004150 104516 TRAP 116
Firstly TRAP 116, just described above, is used to reset the running state of the program.
004152 005067 CLR 13660
Memory location 13660 is cleared. When executing, this memory location is used to store the line number of the currently executing line.
004156 016701 MOV 13662, R1 004162 005201 INC R1
The content of memory address 13662 is then copied into R1. This memory location contains the memory address of the beginning of the program code. The first character in the program code area is a linefeed. This is so that every line in the program (including the first line) has a linefeed character both before and after it. R1 is incremented so that it now points at the first character of the first command in the program.
004164 012767 MOV #13507, 10050
The value 13507 is moved into memory location 10050. This is the initial "seed" of the random number generator, which will be discussed later. Briefly, if the RANDOMIZE command is not used, the random number generator will generate the same numbers every time a program is run.
004172 012767 MOV #1, 13664 004200 000167 JMP 3004
Finally, a 1 is moved to location 13664. This memory address is used as a flag to indicate whether or not a program is running.
Control then jumps to 3004, which is the main syntax parsing loop, to begin executing the program.
BASIC STOP and END commands
The STOP and END commands are used to stop execution of a running program. The two commands, while similar, are slightly different.
END is placed at the end of a program. In other words, it must be the command with the highest line number in a program. STOP, on the other hand, can be placed anywhere in a program.
In either case, the same code is executed:
004106 104402 TRAP 2 004110 012700 MOV #4132, R0 004114 104466 TRAP 66 004116 104404 TRAP 4 004120 104402 TRAP 2 004122 005067 CLR 13660 004126 000167 JMP 3112 ; This is the string "STOP AT LINE " 004132 052123 004134 050117 004136 040440 004140 020124 004142 044514 004144 042516 004146 000040
Let's see how this works.
004106 104402 TRAP 2
First, TRAP 2 is used to display a carriage return and line feed.
004110 012700 MOV #4132, R0 004114 104466 TRAP 66 004116 104404 TRAP 4 004120 104402 TRAP 2
The value 4132 is moved into R0. As can be seen above, this is the memory location of the string "STOP AT LINE ". TRAP 66 is then used to display that string. TRAP 4 is used to display the currently running line number and then TRAP 2 is used to display a carriage return and linefeed.
004122 005067 CLR 13660
The memory location that contains the currently running line number is cleared.
004126 000167 JMP 3112
Control then jumps back to the main syntax parsing loop.
BASIC RANDOMIZE command
As mentioned above, the BASIC random number generator will generate the same values each time a program is executed, unless the RANDOMIZE command is issued.
Here is the code of the RANDOMIZE command:
010054 016767 MOV 13710, 10050 010062 052767 BIS #1, 10050 010070 000167 JMP 2762
The value in 13710 is copied to memory address 10050. The value 13710 is incremented in a loop in TRAP 0 and TRAP 100 while waiting for an input device to become available. Its value is therefore, effectively, random based on the hardware wait times that have been experienced. This value is copied into memory location 10050, which is effectively the seed of the random number generator. Bit 1 of the value is set, so the value will always be odd.
Control will then jump to 2762, back to the main syntax parsing loop.