MEMSCAN is a utility that loads and executes a 34-byte Z80 machine code routine to scan the system’s memory map. The BASIC loader POKEs the routine into RAM starting at address 65500, then calls it with RANDOMIZE USR 65500. The machine code uses register pairs and compare/jump instructions (including CP and JR NZ/Z) to walk through memory. The result is stored back in memory for the BASIC program or user to inspect. The routine is saved as a CODE file at address 65500 with a length of 34 bytes.
Program Analysis
Program Structure
The program is a classic two-stage BASIC/machine-code loader. Lines 1–4 are REM documentation. Lines 10–30 form a FOR/NEXT loop that READs bytes from DATA statements and POKEs them into RAM at addresses 65500–65533. Line 105 invokes the routine with RANDOMIZE USR 65500, line 115 halts execution, and line 120 saves the machine code block for standalone reuse.
Machine Code Payload
The 34 DATA bytes (lines 40–100) disassemble to a Z80 routine. Reconstructing the bytes:
33,0,0—LD HL,0000h(load HL with start address, likely patched or used as counter)14,1—LD E,16,27—LD B,27(loop counter, 27 iterations — one per memory region/page)62,0—LD A,0197—PUSH BC229—PUSH HL190—CP (HL)(compare A with memory contents)40,3—JR Z,+3(jump if zero)205,65,38—CALL 9793h(ROM routine call)225—POP HL35,0—INC HL/NOP193—POP BC4—INC B62,156—LD A,9Ch184—CP B32,236—JR NZ,-20(loop back)12—INC C62,255—LD A,0FFh185—CP C32,228—JR NZ,-28(outer loop)201—RET
The routine uses nested loops controlled by registers B and C to walk through memory, comparing each byte against 0 and 0FFh — the two sentinel values that indicate unoccupied or ROM-filled regions respectively.
Key BASIC Idioms
RANDOMIZE USR 65500— standard idiom for calling a machine code routine and discarding the return value.READ / POKEloop — the conventional method for embedding binary data in a BASIC listing without a separate loader file.SAVE "MEMSCAN" CODE 65500,34— saves only the machine code block, allowing the routine to be loaded independently of the BASIC program later.
Notable Techniques
Placing the machine code at address 65500 (0xFFDC) puts it in the top 36 bytes of the 64K address space, above the normal BASIC and UDG area, minimising interference with the running system. The routine scans with two nested loops using B and C as counters — B cycling through values up to 0x9C (156) and C up to 0xFF (255) — giving a structured traversal of the full address space in 256-byte pages. The dual sentinel test (zero and 0xFF) is a practical heuristic: unpopulated RAM often reads as 0x00 or 0xFF depending on hardware state.
Potential Anomalies
- The byte sequence
35,0decodes asINC HLfollowed byNOP; the NOP is harmless but unusual and may be a padding byte rather than intentional code. INC BafterPOP BCincrements B upward toward 0x9C rather than decrementing, so the inner loop counts up rather than the more conventional countdown — functionally correct but slightly atypical Z80 style.- The outer loop’s
JR NZ,-28displacement should be verified against the exact byte positions; a miscounted displacement would cause the routine to jump into incorrect code, though the program appears to have been published and used successfully.
Content
Source Code
1 REM "MEMSCAN"
2 REM BY RUSSEL ENGLISH
3 REM TIMELINEZ JUNE 1986
4 REM PGM DISPLAYS A MEMORY MAP OF CURRENT SYSTEM
10 FOR X=65500 TO 65533
20 READ Y: POKE X,Y
30 NEXT X
40 DATA 33,0,0,14,1
50 DATA 6,27,62,0,197
60 DATA 229,190,40,3,205
70 DATA 65,38,225,35,0
80 DATA 193,4,62,156,184
90 DATA 32,236,12,62,255
100 DATA 185,32,228,201
105 RANDOMIZE USR 65500
115 STOP
120 SAVE "MEMSCAN"CODE 65500,34
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
