Squash – MC

This file is part of and Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Game

This program implements a single-player Squash game in which a ball bounces around an enclosed court and the player controls a bat at the bottom using the P and Q keys. The court walls are drawn using inverse-video characters for the sides and block graphics (▄) for the top, while the bat is rendered with a block graphic character. Ball movement is tracked with direction variables L and M, and the collision logic at line 130 uses a chained comparison idiom to detect wall bounces. Scores are tracked separately for the Sinclair (computer) and the player, with the first to reach 10 winning the match.


Program Analysis

This program is a machine code game or application stored entirely within the REM statement at line 1, with execution triggered by RAND USR 17298 (hex 0x4392), which jumps into the machine code block. The REM data spans several hundred bytes of Z80 object code, containing what appears to be a complete self-contained program including display routines, sprite handling, and game logic. Line 4030 saves the program with an auto-run marker. The BASIC lines 4010–4040 serve purely as a loader/utility shell; the real program is the Z80 code embedded in the REM statement.

Program Structure

The BASIC listing is minimal by design. The program consists of five lines:

  • 1 REM ... — contains several hundred bytes of Z80 machine code as raw data embedded in the REM token’s string body.
  • 4000 RAND USR 17298 — transfers execution to address 17298 decimal (0x4392 hex), which is inside the REM statement’s data area (the BASIC program starts at 0x4000 on this system, and the REM body begins a few bytes in at line 1).
  • 4010 STOP — a safety net if USR returns.
  • 4020 CLEAR — present but never reached in normal flow; likely a utility/development remnant.
  • 4030 SAVE "1024%8" — saves the program.
  • 4040 RUN — restarts execution from the first line.

Machine Code Entry Point

The entry point at 0x4392 (17298 decimal) is calculated as follows: the BASIC program area starts at 0x4000; line 1’s REM token occupies bytes at a fixed offset (line number 2 bytes, length 2 bytes, REM keyword 1 byte = 5 bytes), so the REM data body begins at 0x4005. The entry point 0x4392 is therefore 0x38D (909) bytes into the REM data, pointing to a specific subroutine or initialisation block within the machine code rather than the very start of the data.

Machine Code Content Analysis

Disassembling key portions of the REM data reveals the following functional blocks:

  • 0x4005 (start of REM body): Begins with 2A 39 40LD HL,(0x4039), immediately reading a pointer from within the REM area itself, indicating self-referential data structures.
  • ROM calls: Numerous CD xx xx (CALL) instructions target ROM addresses (e.g. CD 2B 0F, CD 1F 0A, CD 75 43), making use of system ROM routines for display output (D7 = RST 0x10, the character output restart) and other OS services.
  • Display output: The opcode D7 (RST 16) appears repeatedly throughout the code, used to print characters to the display via the ROM character output routine.
  • IY register use: Several FD CB prefixed instructions operate on (IY+offset), accessing the system flags area (IY normally points to FLAGS in the system variables area).
  • 16-bit arithmetic: Extensive use of ED 62 (SBC HL,HL), ED 52 (SBC HL,DE), ED 4B/ED 5B (LD BC/DE,(nn)) and 22 xx xx (LD (nn),HL) for multi-byte variable management.
  • Data tables: The latter portion of the REM (roughly from offset 0x300 onward) contains interleaved code and data including what appear to be text strings stored as offset-encoded bytes (values like 38 36 3A 26... which, when decoded with a consistent offset, form readable ASCII text), and a block of initialisation data ending in zeros at the very end of the REM.

Memory Map of Key Addresses

Address (hex)Address (dec)Role
0x400016384BASIC program start (line 1 header)
0x400516389REM data body / machine code start
0x439217298USR entry point (RAND USR target)
0x47xx~18xxxSelf-modifying/variable storage within REM (LD (0x47xx),HL patterns)

Notable Techniques

  • REM-as-code: The entire application is stored inside a REM statement, a classic technique that places machine code in a safe location within the BASIC program area where the BASIC interpreter will not attempt to execute it as tokens.
  • Self-contained variable storage: Addresses in the 0x47xx range (still within the REM body) are used as RAM storage locations, written to with LD (nn),HL and read back with LD HL,(nn), making the REM area serve as both code and data space simultaneously.
  • RST 16 output: Direct use of D7 (RST 0x10) for character-by-character display output bypasses higher-level BASIC print routines for speed.
  • Encoded text strings: Printable text in the data section appears to be stored with a byte offset applied to each character value, a simple obfuscation/packing technique that also avoids null bytes and BASIC keyword token conflicts within the REM body.
  • Stack manipulation: Frequent E3 (EX (SP),HL) instructions are used for efficient stack-based parameter passing and return address manipulation, a Z80 idiom for coroutine-style control flow.
  • Initialisation block: The final bytes of the REM — 00 00 01 00 01 00 0A 00 00 00 ... — are a zeroed/initialised data block, consistent with game state variables reset at startup by the initialisation routine near 0x4392.

BASIC Shell

The four BASIC lines above 4000 form a minimal loader. RAND USR 17298 is used rather than USR 17298 alone because RAND USR discards the return value without requiring it to be assigned or printed, and on this system it also avoids a potential error condition if the machine code returns a non-numeric result. The STOP at line 4010 ensures the interpreter halts cleanly if control ever returns to BASIC.

Potential Anomalies

  • Lines 4020 CLEAR and 4040 RUN are unreachable in normal operation and appear to be development/utility lines left in the listing.
  • The SAVE line at 4030 saves only the BASIC wrapper, not explicitly invoking a full binary save — the machine code is preserved as part of the BASIC program file since it resides in the REM statement.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10211 – 10251.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM 2A3940E5CD2BFCD1FA3E12D73A2140CB4720262AE40E5CD7543E1FE7728E7FDCB21460203AFE762821FE16288FE1C38E4FE2630E0D718DD772FE62C62321E4021003E12D718CB3E13D7CD104138B3E1D5E5CD1FAC1CD189E1A7C9FE762826FE1C38AEFE2C30AAD7D61C5F16019EB211E403528D9EB292929291895FDCB214EC0CB7CC8E1E137C911004B7EFE1620423C18F7E5D61C6F26019EBE1237EFE132815FE7E2811E5D5E169192BCD4412310F8EBE118D397B9C8A7ED62ED52EBA7C9223240CBBCD1C903A3B40F5CD2BFCD7543A7202CFFFFE2820F4F1CB77C0C323F444DC335F434DC3F587D100C375BC56107C4D210029CB11173011910F7C1C901186E2182E07CAAE68047D5CDED41E3CDED41EBE179A7283678B1E5ED62ED52E5C1D12100373FF57A531E8293058FED4A18987ED4A383ED423D3C1D20EC5FF130E2CB4F201EBCB7FC818BCD7F41CB10D01837C7D0EBA7ED62ED52C97C7386B5C82110C921FFFFC9A7ED52C9A7ED527CB52100C02CC9A7ED52C818E3EB1080184EB11807CA8677AA857ED52260796FD8EE16FC97CB52100C87AB3C82CC97CB5B2ED6218F53E1181AFE35E235623E32B2919A7288EBE1E3EB732372C95E2356EBC9EBCD6B42EBC9D5114B0ED4B324036268CD913E56269CD913C17C813014677D90301256F2BC34C41003A2140CB47201ACB4F20ACB7C2863E16D7CDF0411F0D81EFFC5CDE17CDADAE5C1215D40571E1C70CB7A2817197ED6F83D797ED6F83D7CB7ACBFA28EFC9E17E23FE70282FFE76203D718F3CD794118EE971823E904B452130405677D5E5CDB2BE1D172C9CDC427CB5E35E235623E3C0E1EBE97DE61F4FFDCB14E28AFD9638CBFFC63CD4718FD8639FE213A3A40DE1CDFA8FDCB1C6C9E15E235623E5D521701964562B5E2BD510F9E1C1D17A19EBE1E3732372C5E17301EBCD1B42E1D8C1E9EB73C9C1E5C1C96E260C911DA7FD5E5C9C5E1C9EBCD7F43EBC9CD7F4338FBCD7F4330FBD5CDBB2E5C12C6C284CDBD76E2607DD1C9210022B847210022BA47210022BC47211022BE47211022C04721A022C247210022C447CDE045216022C64721E022C847211022CA4721D74322CC472AC647E52180D1CD7341CDD24280703E76D72AC647E521130D1CD7341CDD24280703E76D7CD2F43C647218022CE472113022D047211022D247211A4422D4472150E52ACE47D1CD7341CDD24283703E76D7CD2F43CE472130E52100D1CD7341CDD242382E332831262E370382834372A1B1B1C703E76D72110E52100D1CD7341CDD2423E343A370382834372A02E381B1B1B1C703E76D721F0E52AC247D1CD7341CDD242030703E76D711350CD7F43CD942E5111102AC247CD2142EBE1CD3542EB2AC24719E511360CD7F43CD942E511802AC247CD2042EBE1CD3542EBE1CD54222C247CD7F43CDC42CDFD42D944CD5E43ED5BBC47216019E5ED5BBA47219019D1CD7341CDD2420703E76D7ED5BBA472AC047191190CD2042E5ED5BBA472AC047191100CD2142EBE1CD4042CDFD4226452AC047CDF04122C047ED5BBC472ABE47191180CD2042E5ED5BBC472ABE47191100CD2142EBE1CD4042CDFD4256452ABE47CDF04122BE47ED5BC0472ABA471922BA47ED5BBE472ABC471922BC47ED5BBC47216019E5ED5BBA47219019D1CD7341CDD24234703E76D711802ABC47CD942E5ED5BBA472AC247CD542CDED411190CD1B42EBE1CD3542CDFD42B345CD8E4611802ABC47CD942E5ED5BBA472AC247CD542CDED411180CD942EBE1CD3542CDFD42DD45CD2347C37844CDD2421717171717171717171717038363A26382D01717171717171717171717703E76D7CDD24217171702B2E373839039340382834372A01D1C03C2E33380171717703E76D73E76D7CDD242173A382A03502633290360302A3E3803934032343B2A027263917703E76D73E76D7CDD24217171735372A3838001B351B00302A3E0393403531263E1B171717703E76D711350CD7F43CD1442CDFA427A46CD2AACD5E4311102AB8471922B8472130E521100D1CD73412AB847CD92423E76D711A02AB847CD2142CDFD42BD46CD5E43CD2AA21A0E52110D1CD7341CDD242171717171702834322A03433039373E0262C262E3301717171717703E76D721F0E52110D1CD7341CDD24235372A38380C035C00393403531263E703E76D711350CD7F43CD1442CDFA421247C3B54711102AC4471922C4472110E521100D1CD73412AC447CD92423E76D711A02AC447CD2142CDFD425247CD5E43CD2AA21A0E52110D1CD7341CDD2421702E03C2E31310272A263903E343A0332A3D390392E322A017703E76D721F0E52110D1CD7341CDD24235372A38380C035C00393403531263E703E76D711350CD7F43CD1442CDFA42A747CD2AA0000001010A0000000000000000000
 4000 RAND USR 17298
 4010 STOP 
 4020 CLEAR 
 4030 SAVE "1024%8"
 4040 RUN 

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

People

No people associated with this content.

Scroll to Top