The Mystery of the Wizard's Castle REM Statement
The Mystery of the Wizard's Castle REM Statement
The Mystery of the REM Statement
In the 1980 microcomputer game The Wizard's Castle, written for the Exidy Sorcerer, the first line of source code appears as 10 REM"_(C2SLFF4. While it looks like a typo or garbage text, this line is actually a Z80 machine code routine disguised as a BASIC comment, used to simulate a RANDOMIZE function for seeding the game's pseudo-random number generator (PRNG).
How the Machine Code was Hidden
On the Exidy Sorcerer, the BASIC interpreter tokenizes commands and stores them as a linked list in RAM starting at address 469. The structure of a program node includes the next pointer, the line number, the tokenized command, and the text of the line.
For the first line of the program:
- Address 469-470: Next pointer
- Address 471-472: Line number (10)
- Address 473:
REMtoken (0xC3) - Address 474: The start of the
REMtext
By using the USR() function—which jumps to a machine code address specified via POKE commands at addresses 260 and 261—the game executes the text of the REM statement as actual Z80 instructions. Specifically, the code POKE 260,218: POKE 261,1 tells the USR() function to jump to address 474, which is exactly where the REM text begins.
Dissecting the Z80 Routine
Initial attempts to disassemble the REM text as ASCII failed because the characters in the original magazine listing were not ASCII-encoded. When the actual bytes from a tape image were analyzed, the routine was revealed to be:
LD A,R ; Copy R register to accumulator
JR Z,-4 ; If result is 0, jump back to previous instruction
LD (F7FF),A ; Copy accumulator into address F7FFh
RET ; Return to BASIC
The PRNG Seeding Process
- Entropy Source: The routine reads the
Rregister, which increments frequently during instruction fetches, providing a semi-random value based on exactly when the user starts the game. - Zero-Check: It ensures the value is not zero to avoid poor PRNG seeding.
- Memory Mapping: The value is stored at address
0xF7FF, which corresponds to the lower-right character position of the memory-mapped screen text. - BASIC Retrieval: The BASIC code then uses
T = PEEK(-2049)(where -2049 is 0xF7FF) to read this value and seed theRND()function usingQ = RND(-(2*T+1)).
Because the R register only increments its low 7 bits, this technique limited the game to only 127 possible randomly generated dungeons.
The "Typing-In" Paradox
During the 1980s, programmers typed code directly from magazines. However, the REM statement in The Wizard's Castle could not have worked if typed as literal ASCII characters. There are two likely explanations for how original users implemented this:
- Direct POKING: The author may have typed a placeholder
REMand then usedPOKEcommands to manually insert the non-ASCII bytes into memory. - Special Key Combinations: Research suggests the Exidy Sorcerer had
Graphic+Shiftkey combinations that allowed users to enter tokens and values from 0x80 to 0xFF, which would map to the glyphs seen in the listing.
Technical Insights from the Community
Analysis of the technique highlights the deterministic nature of early home computers, where fixed RAM locations and a lack of multiprocessing allowed for the seamless blending of BASIC and machine code.
"Most type-in hybrid BASIC-machine language programs would have numerous DATA statements with opcodes and a loop to READ and POKE them... Commodore 64 BASIC's LOAD"WHATEVER",8 command would load a file of any size in the BASIC text area without validation." — @RiverCrochet
Similar techniques were used on other platforms, such as the Sinclair ZX81, where REM statements or other ignored lines were used to store machine code in the absence of dedicated memory blocks or DATA statements.