PrintScreen

Developer(s): Peter McMullin
Date: 1985
Type: Program
Platform(s): TS 1000
Tags: Printer

PrintScreen is a utility that uses machine code routines, entered via BASIC, to send the screen contents to a printer through a Memopak interface. The program first lists itself (line 10), then prints characters 0–191 while skipping the range 64–127 (line 30 filters these out using an AND mask), and finally calls machine code at USR 16528 and USR 16840 to perform the actual screen dump. The REM line 0 encodes the machine code routine directly in its token stream, a well-known ZX81 technique for embedding binary data in a BASIC listing. Lines 1–8 display a decorative banner explaining the utility and its invocation method (RAND USR 16528).


Program Analysis

Program Structure

The program is organized into two distinct regions: a set of REM lines that carry the machine code payload and a short BASIC driver that exercises and saves the routine.

Line(s)Purpose
0 (first)Machine code embedded in REM token stream
1, 0, 0, 0, 0, 0, 7, 8Decorative banner / documentation REMs
10LIST 1 — lists the program from line 1
20–40Loops through characters 0–191, printing those outside 64–127
50Calls machine code at USR 16528 and USR 16840
60STOP
70SAVE "PRTSC[R]"
80RUN

Machine Code Embedding in REM

The first REM at line 0 contains the machine code routine for the print-screen function. This is the classic ZX81 technique of storing binary data inside a REM statement: the interpreter never executes the body of a REM, so arbitrary bytes — including Z80 opcodes — can be stored there safely. The entry point is at address 16528 (the start of RAM, 16514 + 14 bytes of system variables), and a secondary entry or helper routine sits at 16840. The RAND USR 16528 invocation documented in the banner calls directly into this embedded routine.

Character Filter in Line 30

Line 30 uses the idiom CHR$ N AND (N<64 OR N>127). On the ZX81, the boolean expressions N<64 and N>127 evaluate to 1 (true) or 0 (false). When the condition is false (i.e., N is in 64–127, the alphabetic and keyword range), the AND forces the argument to CHR$ to zero, printing CHR$ 0 (a space) instead. This neatly sidesteps characters that would otherwise invoke BASIC keywords or produce unwanted token output during the display pass.

USR Call Chain in Line 50

Line 50 reads:

  • RAND (USR 16528 + USR 16840 + USR 16528)

Each USR call jumps to the machine code, executes it, and returns a value (typically the BC register pair). The results are added together and passed to RAND, which simply discards the value — the entire expression is evaluated for its side effects (the three print-screen calls). Calling USR 16528 twice suggests the routine may need to be invoked more than once to complete a full 192-line screen dump, with USR 16840 handling a mid-point or secondary pass.

Multiple Identical REM Lines at Line 0

Several REMs share line number 0. On the ZX81, duplicate line numbers are legal; the system stores each as a separate record in the program area and LIST displays them in sequence. This is exploited here to pack the decorative banner into lines that sort before line 1 yet after the machine code REM. LIST 1 at line 10 deliberately skips line 0 entirely, presenting only the human-readable banner to the user.

SAVE and RUN Lines

Line 70 saves the program under the name PRTSC (the [R] escape represents the letter R in the zmakebas encoding, giving the filename a trailing R). Line 80’s RUN restarts the program after saving, providing a convenient loop for repeated use without manual re-entry.

Notable Techniques Summary

  • Machine code stored in a REM statement at the start of RAM (address 16528).
  • Boolean arithmetic used as a character mask in CHR$ N AND condition.
  • Three USR calls chained inside a single arithmetic expression, results discarded via RAND.
  • Duplicate line-0 REMs used to layer machine code below the human-readable banner.
  • LIST 1 used to suppress the machine code REM from normal display.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   0 REM .INKEY$ ▒.#> \,,.# ▝ █5▙RND▞▛#LN PD7( RAND LN [D]RNDY.LN PDYM#PDE£RND▞-VAL 7 FAST5[,,]RND▞▌#LN PD7( RAND  LPRINT ▞4VAL #ACS #4" FAST5[?]RNDACS [Y]LN  POKE RND/"ACS [Z] FAST5[?]RNDACS  RETURNLN  POKE RND LPRINT 7AT ( TO Y\~~LN PDY$LN PDAT LN #?K[I]([V]TAN 5 SAVE 1W#)▒ ;( CLEARLN [Q]INKEY$ ACS # FOR CODE ASN \~~LN ""INKEY$ ( PRINT LN [5]INKEY$ LN [M]INKEY$ ACS # FOR CODE ASN \~~LN ""INKEY$ ( PRINT LN [5]INKEY$ LN [M]INKEY$ ACS # FOR CODE ASN \~~LN ""INKEY$ ( PRINT LN [5]INKEY$ LN [M]INKEY$ ACS # FOR CODE ASN \~~LN ""INKEY$ ( PRINT LN [5]INKEY$ LN [M]INKEY$ ACS # FOR CODE ASN \~~LN ""INKEY$ ( PRINT LN [5]INKEY$ LN [M]INKEY$ ACS # FOR CODE ASN \~~LN ""INKEY$ ( PRINT LN [5]INKEY$ LN [M]INKEY$ ACS # FOR CODE ASN \~~LN ""INKEY$ ( PRINT LN [5]INKEY$ LN [M]INKEY$ ACS # FOR CODE ASN \~~LN ""INKEY$ ( PRINT LN [5]INKEY$  LPRINT TAN ACS  COPYTAN ACS  RUN TAN ACS  LOAD TAN ACS  SCROLLTAN ACS  TO TAN ACS NOT TAN ACS INT TAN ACS SIN TAN 5[?]RNDACS #C▝ INPUT  COPY PRINT LN PD LET #PDSGN  LPRINT /▘SGN  FASTSTR$ [J])[,,]INKEY$ ▞▒TAN  FOR <<<7TAN **E£RND:-▞47#LEN █#( RAND 7$4 NEXT TAN ********
   1 REM  ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜
   0 REM  ▌  P.MCMULLIN,1985  ▐
   0 REM  ▛\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~▜
   0 REM  ▌  RAND USR 16528 = ▐
   0 REM  ▌    PRINT SCREEN   ▐
   0 REM  ▛\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~\~~▜
   7 REM  ▌MEMOPAK I/F VERSION▐
   8 REM  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  10 LIST 1
  20 FOR N=0 TO 191
  30 PRINT CHR$ N AND (N<64 OR N>127);
  40 NEXT N
  50 RAND (USR 16528+USR 16840+USR 16528)
  60 STOP
  70 SAVE "PRTSC[R]"
  80 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top