Night Gunner is a shooting game that uses machine code (invoked via RAND USR 20337) for its core gameplay loop, with BASIC handling initialization, display setup, and high-score management. The program uses LPRINT and AT/TAN/FAST/SLOW idioms embedded within REM statements to store and execute encoded data and machine code routines. Block graphics characters are used extensively to render the game’s visual elements, including the playfield and aircraft graphics. The BASIC loader REMs at lines 5, 10, 15, and 20 contain densely packed tokenized data that serves as both the machine code payload and display rendering instructions. A high-score table with named entries is maintained and displayed using formatted LPRINT output.
Program Analysis
Program Structure
The program consists of five lines: four large REM blocks (lines 5, 10, 15, 20), a SAVE command at line 25, and the machine code entry point at line 30. The actual game engine resides entirely within machine code that is stored as tokenized data inside the REM statements. The BASIC program’s sole runtime purpose is to invoke that machine code via RAND USR 20337 at line 30.
REM-as-Data Technique
This is a classic loader pattern: the four REM lines (5, 10, 15, 20) hold raw bytes — machine code, lookup tables, sprite data, and string resources — in positions immediately following each REM token in memory. Because the ZX81/TS1000 stores the entire line including REM body verbatim in RAM, arbitrary byte sequences can be embedded there and accessed by absolute address. The RAND USR 20337 call jumps directly into this binary payload.
Key BASIC Idioms
RAND USR 20337— transfers control to machine code at the fixed RAM address where theREMdata begins; this is the canonical ZX81/TS1000 machine-code launch technique.VAL "number"used inGO TO/GO SUBtargets within the encoded data — a standard memory-saving idiom.- Block graphics characters (
▘▝▖▗▌▐▀▄▛▜▙▚▟█) are embedded directly in the REM data to represent sprite and playfield tiles. FAST/SLOWtokens appear inside the REM data, consistent with the machine code using them as byte values rather than executed BASIC commands.LPRINT,AT,TAN,COPY, andSAVEtokens visible in the disassembly are tokenized bytes being repurposed as data, not executed BASIC statements.
Display and Graphics
The title screen text visible in the REM data includes the strings [P][R][E][S][S], [R][U][N], [T][O], [P][L][A][Y], [B][E][S][T][S][C][O][R][E][O][F][T][H][E][D][A][Y], and a mission identifier [-][M][I][S][S][I][O][N][-][-][-][-][1]. These are rendered by the machine code using direct screen writes. The dense block-graphic sequences in line 5’s REM body represent the game’s visual scenery or sprite frames for the night sky and gun/aircraft imagery.
High Score System
Evidence within the REM data shows variables named M[O], M[P], M[Q] used alongside LPRINT tokens and ACS/LN arithmetic sequences, consistent with a three-entry high-score table. Score comparison and conditional branching sequences (visible as IF, GOSUB, RETURN tokens) manage table updates. The SAVE "NG" at line 25 persists the program (including any modified REM data holding scores) back to tape.
Notable Techniques
- Scores and game state are preserved between sessions by saving the entire program — modified REM bytes act as non-volatile storage without a separate data file.
- The use of
GOSUB PI,GOSUB [K],GOSUB [R]patterns in the REM data are BASIC tokens whose numeric values serve as operands or subroutine-vector bytes in the machine code, not actual BASIC subroutine calls. - Sprite movement and collision detection are handled entirely in Z80 machine code, keeping gameplay fast despite the inherently slow BASIC interpreter.
- Multiple
COPYtokens in sequence within the data (e.g.,COPY3> COPY3> COPY$+) suggest screen-copy or buffer-flip operations driven by the machine code.
Anomalies and Observations
- The trailing
00000000000sequences at the end of lines 10 and 20 are padding bytes (zero is theFORMATtoken on ZX81, harmless as data) used to align or fill the REM block to a required length. - Line 5’s REM contains what appears to be a copyright notice:
(C)DIGITAL INTEGRATION 1982— confirming commercial authorship and dating the binary. - The
DIM Ytoken sequence in line 10’s data suggests the machine code sets up array storage for game variables at runtime.
Content
Image Gallery
Source Code
5 REM (C)DIGITAL INTEGRATION 1982##Y█LN 7#LN GOSUB PILN CHR$ RNDE£RND▘▞ \,, FOR ▘= 5[M]INKEY$ GOSUB [K]E£RND▘[T]▝\,, FOR ▘+ 5LEN INKEY$ GOSUB [K]E▐#6#RND FOR 7LN [-]#TAN E£RND▘# \,,##▘) 5TINKEY$ GOSUB [K]##▘( \,,##▘) 5#INKEY$ GOSUB [K]##▘( \,,##▘) 5#INKEY$ GOSUB [K]E£RND▘+▝\,,##▘* 5#INKEY$ GOSUB [K]##▘\~~ \,,##▘* 5▄INKEY$ GOSUB [K]##▘\~~ \,,##▘* 5[,]INKEY$ GOSUB [K]TAN ▌▜▌█▌█▌▄▟█▌█▐█▙▖▄▌▙▘█▌█▌▙▐█▌▄▐██▌█▙█▙█▙█▙▄▟█▙█▟██▙█▀▀██▜▛██▜█▜█▛█▛██▀▀██▀▜▐▀██▐▌██▗▜▐█▌▞▌██▝███▝▟▝▘██▞▚██▐▙▐█▌█▖██▝▀██▐▞ [P][R][E][S][S]██[R][U][N]██[T][O]██[P][L][A][Y][B][E][S][T]█[S][C][O][R][E]█[O][F]█[T][H][E]█[D][A][Y] FASTVAL Y[-]#7Y[O]#7Y[-]#▘6 [R] GOSUB PIY[.]#\,,FF▞ COPY:=$4 CLEAR( RAND Y█#7#7#▘6 [R] GOSUB PI#LN GOSUB PIAT LPRINT U9RNDACS #"" LPRINT TAN LN [3]RNDE£RND▘# \,,▞0)5 LN <=INKEY$ 7( IF ▞▞LN <=INKEY$ ;( IF ▞.LN <=INKEY$ F( IF ▞£LN <=INKEY$ ;( IF ▞.LN <=INKEY$ 7( IF ▞$LN <=INKEY$ [R] GOSUB #( SAVE ▞/LN <=INKEY$ F( IF ▞▌LN <=INKEY$ [R] GOSUB #( SAVE ▞"LN <=INKEY$ 7( IF FY[-]#7Y[O]#7Y[-]#▘6 [R] GOSUB PIY[.]#Y:MQRNDY▝MRRNDLN UNPLOT # LN [3]RNDE£RND▘# \,,)5 ▞/LN <=INKEY$ F( IF ▞▒LN <=INKEY$ ;( IF ▞;LN <=INKEY$ 7( IF ▞\~~LN <=INKEY$ ;( IF ▞.LN <=INKEY$ F( IF ▞\~~LN <=INKEY$ [R] GOSUB #( SAVE ▞:LN <=INKEY$ 7( IF Y[O]#LN ABS #LN GOSUB PI #;PI FASTVAL E£RND▘ RUN Y[.]\,,#▘5 \,,#\,,#\,,\,,#\,,#\,,#▘# [R] GOSUB PIY[-]#7#7#7Y[+]#7Y[-]#7#7#AT LPRINT TAN FASTVAL E£RND7▞-:4#7$4 CLS7( PLOT AT LPRINT TAN FASTVAL E▄# GOSUB #▟#▞ \,, GOSUB #▙#▞ [R] GOSUB PI▘# \,,6▄#LN ##Y# AT LPRINT TAN FASTE▄#6#RNDE£RND7LN [-]# LPRINT TAN FASTSTR$ E▐#6#RNDE£RND): ;LN [-]#SGN LPRINT TAN FASTSTR$ E£RND)0 ;U[R]#LEN [0]#SGN LPRINT TAN STR$ VAL FAST[J]M[O]#M[P]#M[Q]#5## GOSUB ##RND▞(ACS #CA# FAST5[Q]#▚B LPRINT M[Q]#7# FAST5[P]#[:]B LPRINT M[P]#7# FAST5[O]#[:]B LPRINT M[O]#7/▀777ACS 7ACS >(LN U[O]# NEW?4OY█ LPRINT #7U[P]#ACS ZACS ZACS ZACS Z4MY█#7U[P]# NEW?4KY█#7U[Q]#ACS ZACS ZACS ZACS Z4IY█#7/GLEN [0] LPRINT #7U[P]#ACS ZACS ZACS ZACS ZLEN [0]#7U[P]# NEW?LEN [0]#7U[Q]#ACS ZACS ZACS ZACS ZLEN [0]#7U[Q]# NEW?LEN [0]#AT SGN TAN #B▀▜#▘[>]▟ [-]RND #4 8( >▌ #▝ C▘ # M - ▒ ▖ ▝ ▘ ## 3 "\,,::\~~£." COPY3> COPY3> COPY$+ COPY3+)4+████[3]▘ #(9 ▀▒▞▀ :▖▛ ▀ UNPLOT #,[S]###TAN 00000000000
10 REM ## FASTLN 9#LN PLOT #LN TO # LPRINT TAN FASTURRNDLN ▖#UQRNDLN 2#Y[-]#7Y[O]#7Y[-]#VAL ▘6 [R] GOSUB PIAT Y[.]# LPRINT TAN VAL STR$ E£RND7#- ▞▌ACS 7ACS >( IF #▞ \,, GOSUB #SGN AT TAN STR$ #- ;SGN TAN FAST# RETURN 4\~~5RRNDOLN INT ##[K]# RETURN▘4\~~5RRNDPLN SIN ##[K]# RETURN▝4\~~5QRNDOLN [Z]##[K]# RETURN▀4\~~5QRNDPLN [Q]##[K]# RETURN▖4)5QRNDPLN [Q]#5RRNDPLN SIN ##[K]# RETURN▌4)5QRNDOLN [Z]#5RRNDOLN INT ##[K]# RETURN▞4)5QRNDOLN [Z]#5RRNDPLN SIN ##[K]# RETURN▛4:5QRNDPLN [Q]#5RRNDOLN INT # LPRINT ▌ATN NOT #TAN ACS #COS Q LN NOT #TAN #CHR$ 2 SAVE Q1/ POKE #CHR$ ▝ LIST Q▝/ GOTO #CHR$ + SAVE Q=/ SLOWUORNDACS Z FAST5[E]#[I]▞▌ACS ?( UNPLOT # NEW?LEN ▀# GOSUB #ACS ? NEW▛# LPRINT TAN FASTVAL GOSUB #9RND5 COPY COPY[R] GOSUB PIASN L#5 LOAD TO [R] GOSUB PI4?5RRNDAT PPLN O#LN SIN ##M#5 LOAD LOAD [R] GOSUB PI4?5RRNDAT OOLN RND#LN INT ##M#5 LOAD RUN [R] GOSUB PI4?5QRNDAT PPLN ##LN [Q]##M#5 RUN TO [R] GOSUB PI4?5QRNDAT OOLN ##LN [Z]##M#5 SCROLLINT [R] GOSUB PI4,5QRNDAT OOLN ##LN [Z]#5RRNDOOLN RND#LN INT ##M#5 LOAD NOT [R] GOSUB PI4,5QRNDAT PPLN ##LN [Q]#5RRNDPPLN O#LN SIN ##M#5 LOAD SCROLL[R] GOSUB PI4,5QRNDAT PPLN ##LN [Q]#5RRNDOOLN RND#LN INT ##M#5 SCROLL TO [B] GOSUB PI4,5QRNDAT OOLN ##LN [Z]#5RRNDPPLN O#LN SIN ##M#5 FOR <>[B] GOSUB PIASN $#5 FOR GOSUB [B] GOSUB PIASN 8#5 FOR PRINT [B] GOSUB PIASN V#5 NEXT <>[B] GOSUB PIASN ##5 STOPLN [B] GOSUB PIASN ##5 FOR STR$ [B] GOSUB PIASN ["]#5 FOR FAST[B] GOSUB PIASN [H]#5 STOP<>[B] GOSUB PIASN INT #AT LPRINT TAN # RETURN▛COS RETURN COS RETURN▌COS OTAN # RETURN▖COS RETURN▘COS RETURN▞COS PTAN # RETURN▞COS RETURN▝COS RETURN▌COS OTAN # RETURN▖COS RETURN▀COS RETURN▛COS PTAN VAL ▞COS :$$4 CLEAR( RAND AT TAN VAL ▞ COPY:M$4 CLEAR( RAND AT TAN VAL ▞▞[J]LN 7#Y█LN [.]#LN ##Y█LN 7#[J]LN [.]#LN ##( NEWAT TAN FASTVAL STR$ E£RND▘[C] \,,LN £#E£RND▘[H] \,,LN £#E£RND▘[M] \,,LN £#E£RND▘[U] \,,LN £#E£RND▘TAB \,,▞£LN :#E£RND▘[R] \,,▞▒#7( UNPLOT ▘4 \,,▞▒#F( UNPLOT E£RND▘#▘\,,#7#7#▘5 \,,#F#F#E£RND▘#▝\,,#7#SGN AT LPRINT TAN ▞:)4 #7#;( IF TAN 5[<]#▞▖# RETURN█4▀Q[-]7( PLOT Y>E£RND)#▘; FOR 5▗#▘▘ STR$ FASTVAL GOSUB [K]AT LPRINT SGN ▀ RETURN>ATN [T]# RETURN>CODE [;]#.X4 DIM Y:▘> STR$ FASTVAL GOSUB [K]AT LPRINT SGN RETURN▒ATN ##LN [;]#.X4 GOTO Y)▘) <7STR$ FASTVAL GOSUB [K]AT LPRINT SGN ". RETURN)ATN [;]#< RETURN)CODE [T]#X4 SCROLLTAN [(]O▘[<][-][M][I][S][S][I][O][N][-][-][-][-][1]█ FASTVAL ##▘4 [R] GOSUB PI▞▝:[X]#LN ##:[+]#LN ##( PAUSE :█#AT LPRINT TAN VAL ▞▖LN ##( CLSAT TAN VAL ▞▌LN [;]#( CLSAT TAN LN ▄#( PAUSE :█#AT LPRINT TAN VAL ▞▖LN ▄#( CLSAT TAN VAL ▞▌LN [S]#( CLSAT TAN Y▞M>=ZMRRND##Y█XXMT##MYPU#MPTAN
15 REM ## FASTVAL STR$ 5[▒]#ACS #C\,,E[~~]#6QRNDLN ##5[▒]#ACS #C\,,E[£]#6QRNDLN ##5[▒]#ACS #C\,,E[:]#6QRNDLN ##5[▒]#ACS #C\,,E[(]#6QRNDLN ##LN GOSUB PI5[▒]#ACS #CYE[~~]#6QRND GOSUB #[G]##LN PEEK #EQRND6[~~]## GOSUB #[G]# FAST5▗#ACS # LPRINT 40#CHR$ < PAUSE [;]## RETURN▘4)G#M[+]#M[-]##M[*]#5▗#ACS EXP 5[▒]#ACS #CYE[£]#6QRND GOSUB #[I]##LN PEEK #EQRND6[£]## GOSUB #[I]# FAST5▗#ACS # LPRINT 40#CHR$ < PAUSE THEN## RETURN▘4)G#M[/]#M[;]##M[,]#5▗#ACS CHR$ 5[▒]#ACS #CYE[:]#6QRND GOSUB #[K]##LN PEEK #EQRND6[:]## GOSUB #[K]# FAST5▗#ACS # LPRINT 40#CHR$ < PAUSE 7## RETURN▘4)G#M[.]#M[0]##M[1]#5▗#ACS THEN5[▒]#ACS #CYE[(]#6QRND GOSUB #[M]##LN PEEK #EQRND6[(]## GOSUB #[M]# FAST5▗#ACS # LPRINT 40#CHR$ < PAUSE ### RETURN▘4)G#M[2]#M[3]##M[4]#5▗#ACS NEWSGN AT LPRINT TAN URRNDLN ▖#UQRNDLN 2#Y█#7#7#▘6 [R] GOSUB PI#TAN FASTVAL GOSUB #9RND 5 FOR <>LN ATN #5 FOR GOSUB LN ATN #5 FOR PRINT LN ATN #5 NEXT <>LN ATN #5 STOPLN LN ATN #5 FOR STR$ LN ATN #5 FOR FASTLN ATN #5 STOP<>LN ATN #5 CLS CLEARLN ATN #AT LPRINT TAN [R] GOSUB PI""U[C]#[R]COS 5▗#ACS #""CHR$ ▝M[C]#ACS LEN LN NEW#TAN FASTVAL E£RND▘[Q]▝\,,Y[A]#7Y[M]#7#7Y[O]#U[C]#[R]C£ACS JACS JW#Y[▒]7#( UNPLOT U[C]#ACS JACS JW#Y0[(]#Y█7#( UNPLOT AT LPRINT TAN FASTVAL STR$ E[S]# GOSUB #[U]#- GOSUB #[V]#[R] GOSUB PI PAUSE PI#E[S]#LN [F]#/▞E[S]#[R] GOSUB #▘6 [R] GOSUB PI;..6[S]##M[U]# GOSUB #[X]#[R] GOSUB PI PAUSE ##LN [N]#5▗#ACS ▚/VE[S]#▘# [R] GOSUB PI FAST GOSUB #[X]#[R] GOSUB PI LPRINT IF [-]#Y▞# GOSUB #[U]#- ....[R] GOSUB #Y▚#/)E£RND)#▘;# RETURN[+]C▌5▗#ACS INPUT SGN AT LPRINT TAN [R]Y█# GOSUB ##TAN FASTVAL E£RND▘=▀\,,6[S]#▘# [R] GOSUB PI6[V]#Y,M[U]#E£RND▘#▘\,,6[X]#5▗#ACS ▚AT LPRINT TAN FASTVAL E£RND▘T▘\,,#▘4 \,,#77#\,,#AT LPRINT TAN FASTVAL E£RND▘ RUN \,,#▘3 \,,#▘▖ \,,#▘X \,,#▘▞ \,,#▘X \,,#▘▖ \,,#▘3 \,,#AT LPRINT TAN FASTVAL E£RND▘[=] \,,#▘2 \,,#▘▞ \,,#▘U \,,#▘\~~ \,,#▘# \,,#▘£ \,,#▘# \,,#▘\~~ \,,#▘U \,,#▘▞ \,,#▘2 \,,#AT LPRINT TAN \,,#▘▞ \,,#▘2 \,,#AT LPRINT TAN 00
20 REM ##VAL FAST)[>]#▘▀ GOSUB [K]U[>]##U[<]#[G]CEU[=]#CHR$ + PAUSE TO #U[=]#LN ▖# FASTU[>]#ACS #4▞LN 2#Y█# LPRINT U[<]# RETURN4C▞LN 2#Y█#5[>]#PLN 6#5[<]#OLN C#5[=]#O#5▗#ACS [Y]CHR$ + IF PRINT #5▗#ACS RETURNU[C]#[R]C▛U▟#ACS #CAACS PLOT /6U[=]#LN ▖# FASTU[>]#ACS #4▞LN 2#Y▚# LPRINT U[<]# RETURN4C▞LN 2#Y▞#5[>]#SGN ▘▀ GOSUB [K]AT TAN ACS #COS Q COPYTAN #CHR$ 4 SAVE Q4TAN FASTSTR$ U[,,]#[R]TAB ▘#5[▒]#U["]# RETURN\~~C▞ RETURN"40/"U[~~]# RETURN$C" RETURN?C▛U[~~]# RETURN:4▒ACS [:][J]M[~~]#/#U[$]# RETURN\~~C▞ RETURN"40/"U[£]# RETURN$C" RETURN?C▛U[£]# RETURN:4▒ACS [-][J]M[£]#/#U[?]# RETURN\~~C▞ RETURN"40/"U[:]# RETURN$C" RETURN?C▛U[:]# RETURN:4▒ACS [2][J]M[:]#/IU[)]# RETURN\~~C▞ RETURN"40/"U[(]# RETURN$C" RETURN?C▛U[(]# RETURN:4▒ACS [A][J]M[(]#/▛5▗#ACS [I]/#U[,,]# RETURN 40E£RND)S▘;Y█#77#LN GOSUB PIY[*]LN TO #5[,,]#ACS EXP /#ACS #4£Y[*]LN PLOT #5[,,]#ACS CHR$ /RNDACS #4£Y[*]LN A#5[,,]#ACS THEN/KY█LN TO #LN PLOT #LN A#LN GOSUB PI5▗#ACS [I]5[,,]#Q 5[▒]#ACS #ATN S#Y#M▟#U[▒]# RETURN▘4▖[J]M[▒]#SGN LPRINT TAN FASTVAL STR$ U[D]##5▗#ACS #CODE 8#5▗#ACS #C▀LN J#ACS #C)5[+]#LN ▜#5▗#ACS #C▖ACS [Y]ACS [:]ACS #C)5[/]#LN ▜#5▗#ACS #C▖ACS [Y]ACS [-]ACS #C)5[.]#LN ▜#5▗#ACS #C▖ACS [Y]ACS [2]ACS #C)5[2]#LN ▜#5▗#ACS #C▖ACS [Y]ACS [A]VAL ▞ COPYY▞X4 CLEAR( RAND AT ([$]SGN AT LPRINT TAN FASTVAL LN [N]#▞$LN 8#LN ##( SAVE ▞▖Y?M[~~]#Y\~~M["]#[J]M[,,]#LN J#LN ##( SAVE AT LPRINT TAN FASTVAL Y?M[+]#M[-]#Y▝M[*]#▞(5[+]#LN ▜#LN ##( PRINT LN ##AT LPRINT TAN LN NOT ## GOSUB #[G]#LN ## GOSUB #[~~]#LN NOT ## GOSUB #[I]#LN ###LEN ▀# GOSUB #[£]#LN NOT ## GOSUB #[K]#LN ###LEN ▝# GOSUB #[:]#LN NOT ## GOSUB #[M]#LN ###CHR$ ▝# GOSUB #[:]#TAN #▙##ACS BLEN ▀#TAN 5 6▐#5 6▄#6[A]#5[▒]#ACS RETURNY#M▙#Y)M[D]#Y▀M[R]#LN [N]#LN ;PIY3M[▒]#U▙# RETURN+C$CHR$ ▛M▙#U[D]#CHR$ ▘M[D]#Y#M▟#E[A]#76[A]#6#RND5[<]#LN [-]#LN ##Y#M[C]#[J]M▗#M[,,]#Y█LN 7#LN GOSUB PILN ##LN ##LN ▜#LN NEW#LN 2#LN ▗#U▗# RETURN C▌LN ##/\~~▞ COPYU▙#X4 CLEAR( SAVE U[▒]# RETURN C[£]5▗#ACS #435▟#PLN :# GOSUB #9RND5[U]<=[R] GOSUB PI4▘TAN 5 RETURN NEXT [R] GOSUB PI4[X]###LN ##U[R]#XC"M[R]#Y#M▟##ACS #E▐# GOSUB #▄##[G] IF ##[R] GOSUB # PAUSE ##E▄#6▐####Y█LN 7#LN ##LN ##LN ▜#LN /#TAN ▒ ▖ ▝ ▘ ▞ 42 ;=▀=▌▝\~~" ;;£??)▖▖▒ ▒▀▝▝▒▀▒ [9]#,##"#TAN 00000000000
25 SAVE "N[G]"
30 RAND USR 20337
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.