Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM— contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.10 LET K=USR 17387— transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.20 SAVE "CAGE"— saves the program to tape.30 RUN 10— restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CBopcodes indicates heavy reliance on bit manipulation instructions (BIT,SET,RES,RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines. - ED-prefixed instructions —
EDopcodes appear frequently, covering 16-bit loads (LD BC,(nn),LD DE,(nn)), block moves (LDIR), andLD A,R/LD A,Iused for pseudo-random number generation or timing. - Block memory operations — sequences ending in
\ED\B0(LDIR) suggest bulk copying of sprite or screen data. - Internal subroutine calls — numerous
CD xx xx(CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement. - Address constants — repeated references to addresses in the
43xxand44xxhex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
| Hex Address | Decimal | Inferred Role |
|---|---|---|
43CB | 17355 | Sprite/object X or position low byte |
43CC | 17356 | Sprite/object Y or position high byte |
43CD | 17357 | Secondary object coordinate |
43D0 | 17360 | Game state / direction flag |
43D1 | 17361 | Velocity or delta counter |
43D2 | 17362 | Additional state variable |
44B6 | 17590 | Screen buffer or sprite data table |
44D8 | 17624 | Graphics/shape data |
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG. - Bit-field state machine — the heavy use of
BIT,SET, andRESon single bytes (visible in theCB 4x,CB 5x,CB 6x,CB 7xranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly. - Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ— several10 Fxbyte pairs (DJNZwith negative offset) implement tight delay or drawing loops without BASIC’s overhead. - Exx / DI shadow registers —
D9(EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CBE\C9E\C9\CBE
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C9E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\C9
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\E5\AE\FA\E1\C9\ED\CB\CD\C9\CBC\D0\AF\BE\C8
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BE\E8\BE\C8\EB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CB\E7\D3A\D1\C6\D8\AF\C9\C9\FE\C8\D5\E1
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\C8\D5\E1\CB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"B\CD\A7F\EB\CDF\CD\BB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EDB\CB\EDB\CD\CBD\A5\CB\CBC\C5C\EB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"F\CBF\CA\FE\C8\E5
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"B\D1\CD\A7\C5
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\CDC\EB\CDC\C8\E5
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\A7\ED\D1\CD\A7\EB\E2\C5\CDA\C1\CB\C8
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\CDC\EB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\AE\F9\C9\D1\CBD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"A\A7\C8D\CB\C0 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"A\FE\C8CA\D0\A7\C8E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C\B7\C9A\D0\A7\C0\E5
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\D5E\FE
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
DC\FE\E1\C9 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\EE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"D\D5
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\AF
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\CBE\E1\C9\CD\FB\C1\CB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\AF\C5C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\D9\D7E
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\BA\CCA\D4\BD
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"EA\D0\AA\B8\CCE\B8
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\B8 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"AE\B9
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\B9FE\B9
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\B9A\FEC
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\EDF
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\B8\EDFA\CC\B8
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\B8A\CBD\B9E\C6\B9
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\C6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\B9\C6\B9EE\CB\C3\AE\CB\C2\AA\CB\CB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CB\CA\CB\D3
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB\D2\CBB\CB\CBB\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C\CD\F1\F5\B3\A2\AA\CB\F5\ED\CDA\F1\CBF\CDA\EDF\CB\F3\CDBE\E8\BD\DA\B6A\D1\A7\CA\CB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CBB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AD\FD\FA\C3\CB\CBB\CB\D6\EDF\FE\C0D\FEE\D0\ED\C1B\B2\D1\B2A\D2F\D5A\B4E\E6\CF\C6
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\AA\C5F\AF\E5\D1 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"B\ED\B0\C1
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BC\C5\FE\D4A\C1\CC\C5FA\D1\CBF
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\FF
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\A0\CDA\FB\C1\B3 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"EA\CC\FE\D8
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB\C3A\CB\FE\CB\C9\FE\F9\FE
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB\CB\FE\D8\CB\D3\C9\E5
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BE\A3F\FFA\CF\BD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\CB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FF\CD\AB\A2\F5\CDC\E5\D9E\EB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\AE\E1\F1
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\AE\EB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\D9\E1\C9 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CB\CB\FA\D8F\C9\CDA itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\B6A\ED\B0
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E\CB\AD\ED\B0\CDA\C9 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C\E8
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\D8\D4 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"D\EA\EA\EA\EA\EA\D6\D6\EA itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C\E8
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\D8\D4\CB\F9\CD\F7\E2\E9 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E\E8
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\DB\C5\F6\CD
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CD
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CD
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CB\C5\D5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CDB
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\D1\C1\F4E\B6\C5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E\FC\C1\F1 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\D5\E5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CD
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\CD\E1\CD\CD\C3\B9
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\E5\D9\C1\CD\F5\CDC\F1\AE\D9\EF\C9
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A
Skip to content
Bat Cage
Bat Cage is an action game in which the player catches a falling egg and then traps a bat inside a cage. The program is driven almost entirely by machine code embedded in the REM statement at line 1, with BASIC serving only as a loader that calls the routine via USR 17387 at line 10. The machine code handles all gameplay logic, graphics rendering, collision detection, and input processing directly. A SAVE command at line 20 preserves the program, and RUN 10 at line 30 restarts the game loop.
Program Analysis
Program Structure
The BASIC listing is minimal by design, consisting of just three lines:
1 REM — contains the entire machine code payload (several hundred bytes) embedded as the body of the remark.
10 LET K=USR 17387 — transfers control to the machine code. The address 17387 (decimal) corresponds to the start of the machine code bytes stored in the REM line’s data area.
20 SAVE "CAGE" — saves the program to tape.
30 RUN 10 — restarts the program by jumping to line 10.
All game logic — movement, collision detection, graphics, timing, and scoring — is implemented entirely in the machine code within the REM statement. BASIC is used solely as a vehicle to load and launch that code.
Machine Code Embedding via REM
Storing machine code in a REM statement is a well-established technique. The BASIC interpreter skips REM line content entirely, so arbitrary binary data can be placed there without interference. The USR function at line 10 computes the Z80 entry point address (17387) and performs a CALL to it, handing control to the machine code. The return value is stored in K, though the game does not use it in BASIC.
Machine Code Analysis
The REM data is a dense Z80 routine. Notable structural features visible in the hex stream include:
- CB-prefixed instructions — extensive use of
CB opcodes indicates heavy reliance on bit manipulation instructions (BIT, SET, RES, RLC, etc.), consistent with sprite/character-level graphics and flag-based state machines.
- ED-prefixed instructions —
ED opcodes appear frequently, covering 16-bit loads (LD BC,(nn), LD DE,(nn)), block moves (LDIR), and LD A,R / LD A,I used for pseudo-random number generation or timing.
- Block memory operations — sequences ending in
\ED\B0 (LDIR) suggest bulk copying of sprite or screen data.
- Internal subroutine calls — numerous
CD xx xx (CALL) instructions with targets within the REM block point to a well-structured internal subroutine architecture covering rendering, input reading, collision, and movement.
- Address constants — repeated references to addresses in the
43xx and 44xx hex range (roughly 17000–17600 decimal) indicate game-state variables stored within or just after the REM block itself.
Key Address Map (inferred)
Hex Address Decimal Inferred Role 43CB17355 Sprite/object X or position low byte 43CC17356 Sprite/object Y or position high byte 43CD17357 Secondary object coordinate 43D017360 Game state / direction flag 43D117361 Velocity or delta counter 43D217362 Additional state variable 44B617590 Screen buffer or sprite data table 44D817624 Graphics/shape data
Notable Techniques
- LD A,R (
ED 5F) — used as a source of pseudo-randomness by reading the Z80 refresh register, a common technique for seeding movement or timing variation without a dedicated RNG.
- Bit-field state machine — the heavy use of
BIT, SET, and RES on single bytes (visible in the CB 4x, CB 5x, CB 6x, CB 7x ranges) suggests individual bits of state bytes encode direction, phase, and collision flags compactly.
- Self-contained variable storage — game variables are stored at fixed offsets within the REM block’s memory region rather than in BASIC variables, avoiding BASIC overhead entirely.
- Loop unrolling with
DJNZ — several 10 Fx byte pairs (DJNZ with negative offset) implement tight delay or drawing loops without BASIC’s overhead.
- Exx / DI shadow registers —
D9 (EXX) appears in the code, indicating use of the Z80 alternate register set for temporary storage during interrupt-sensitive sections.
BASIC Idioms
The use of LET K=USR 17387 rather than a bare RAND USR is a minor stylistic choice; both transfer control identically. The RUN 10 at line 30 provides a simple restart mechanism: if the machine code ever returns to BASIC (e.g., after a game over), the program loops back to re-invoke the machine code rather than halting.
Bugs and Anomalies
No significant BASIC-level bugs are present. The program is straightforward as a loader. Any bugs would reside entirely within the machine code and cannot be fully assessed from a static hex listing alone.
Content
Source Code
1 REM \CB\38\30\0A\CB\39\30\03\3E\87\C9\3E\04\C9\CB\39\30\03\3E\02\C9\3E\01\C9\0E\80\06\02\E5\79\AE\77\23\10\FA\E1\C9\ED\43\CB\43\22\CD\43\C9\CB\6C\28\32\21\D0\43\AF\BE\C8\2B\3E\E8\BE\C8\77\EB\2A\CB\43\22\E7\43\21\D3\43\3A\D1\43\C6\15\86\D8\77\13\AF\12\C9\12\C9\79\FE\37\C8\D5\E1\0C\CB\47\28\0E\23\18\0B\0D\C8\79\D5\E1\CB\47\28\02\2B\1B\CD\A7\40\4F\EB\CD\82\40\4F\18\61\CD\BB\02\ED\4B\CB\43\ED\5B\CD\43\CB\5D\28\A5\CB\65\20\58\CB\5C\28\C5\7C\EB\11\21\00\CB\67\28\1F\CB\4F\CA\91\43\78\FE\26\C8\04\E5\0F\30\1B\19\D1\CD\A7\40\C5\0E\03\CD\9C\40\EB\CD\9C\40\18\13\05\C8\E5\78\0F\30\03\A7\ED\52\D1\CD\A7\40\EB\07\38\E2\C5\CD\9A\40\C1\CB\41\C8\0E\04\CD\5C\41\EB\0E\01\06\02\79\AE\77\23\23\10\F9\C9\11\D1\43\CB\6D\20\06\1A\A7\C8\3D\18\08\CB\45\C0\1A\FE\23\C8\3C\47\3A\D0\43\A7\C8\3E\1C\80\32\B7\44\78\12\C9\3A\D0\43\A7\C0\E5\2A\D5\43\7E\FE\03\28\0D\3C\FE\26\30\03\77\E1\C9\36\1C\2B\18\EE\36\1D\21\D5\43\35\2B\34\34\2B\AF\77\2B\CB\3E\E1\C9\CD\FB\40\C1\CB\09\30\02\AF\47\C5\21\3C\40\01\50\40\D9\21\D7\43\4E\23\46\04\0C\11\00\28\78\BA\CC\82\44\3A\D4\43\BD\38\0A\1E\80\3A\D0\43\AA\B8\CC\81\44\3E\21\B8\28\56\30\20\2F\B8\28\54\38\1A\3E\17\B9\28\51\30\24\2F\B9\28\4F\38\14\3E\24\B9\28\50\30\50\2F\B9\28\46\38\4A\79\FE\3C\28\08\30\0A\ED\5F\2F\B8\20\04\79\ED\44\4F\3A\CC\43\B8\28\04\2F\B8\20\65\3A\CB\43\3D\B9\30\5E\C6\04\B9\30\0B\C6\01\2F\B9\30\53\C6\04\B9\38\4E\18\6E\CB\C3\18\AE\CB\C2\18\AA\CB\CB\18\0A\CB\CA\18\06\CB\D3\18\02\CB\D2\CB\7B\20\71\CB\43\20\67\CB\4B\20\20\CB\53\20\1C\CD\15\43\F1\F5\B3\A2\AA\CB\47\28\09\F5\78\ED\44\47\CD\8A\41\F1\CB\4F\28\09\CD\8A\41\79\ED\44\4F\18\04\CB\57\20\F3\CD\3B\43\3E\E8\BD\DA\B6\41\3A\D1\43\A7\CA\CB\41\0E\0F\CB\7B\28\02\0E\0A\47\79\3D\20\FD\10\FA\C3\CB\41\CB\7B\28\26\CB\78\20\D6\ED\5F\FE\C0\30\3D\FE\95\30\30\3E\20\32\D0\43\78\ED\44\47\18\C1\7B\B2\D1\B2\57\3A\D2\43\5F\D5\5A\18\B4\3E\E6\32\CF\43\C6\02\95\28\AA\C5\4F\AF\47\E5\D1\1B\23\ED\B0\C1\2B\18\9C\C5\FE\80\D4\7A\44\C1\18\CC\C5\4F\3A\D1\43\CB\3F\81\30\02\06\FF\2F\A0\28\06\47\CD\8A\41\10\FB\C1\18\B3\1E\80\3A\CC\43\FE\21\D8\20\02\CB\C3\3A\CB\43\FE\14\30\03\CB\83\C9\FE\25\30\F9\FE\18\30\02\CB\CB\FE\21\D8\CB\D3\C9\E5\70\2B\71\3E\80\A3\5F\16\FF\3A\CF\43\BD\30\01\14\CB\78\28\03\78\2F\47\CB\79\28\03\79\2F\4F\CD\82\40\AB\A2\F5\CD\7C\43\E5\D9\5E\23\56\EB\0A\AE\77\E1\F1\02\AE\77\EB\72\2B\73\23\23\03\D9\E1\23\C9\58\79\80\01\00\05\51\CB\23\CB\12\10\FA\21\D8\44\19\51\5F\19\C9\CD\3A\44\01\20\00\11\B6\44\21\5A\44\ED\B0\0E\1E\11\CB\43\21\AD\43\ED\B0\CD\3A\44\C9\1C\24\38\47\E8\20\12\80\00\D8\D4\44\1D\03\13\13\13\EA\EA\13\EA\EA\27\13\27\EA\D6\13\D6\EA\1C\24\38\47\E8\20\12\80\00\D8\D4\44\CB\F9\CD\F7\25\10\E2\E9\10\1E\06\E8\0A\DB\C5\F6\CD\0F\83\81\CD\2B\0F\CD\2A\0A\11\CB\43\06\16\C5\D5\01\20\00\CD\6B\0B\D1\C1\10\F4\11\85\05\3E\80\21\B6\44\06\15\C5\06\1E\72\23\77\23\10\FC\73\23\23\C1\10\F1\11\01\00\D5\21\17\21\E5\23\01\00\0C\CD\47\44\11\00\01\CD\45\44\E1\CD\45\44\CD\94\43\C3\B9\41\2A\CB\43\11\01\00\01\00\04\18\02\06\07\E5\D9\C1\CD\82\40\F5\CD\7C\43\F1\AE\77\D9\19\10\EF\C9\03\07\2E\03\03\03\03\03\03\03\03\04\39\00\2E\00\32\00\2A\00\3D\87\03\03\03\03\03\03\03\1C\1C\1C\84\01\1E\26\ED\43\E7\43\78\ED\44\47\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-51862 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E\ED\E7\ED\C9
10 LET K=USR 17387
20 SAVE "CAG%E"
30 RUN 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

