ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM— contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.20 RAND USR 16514— transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039/0x4073— internal jump and data pointers within the REM block.0x7840–0x7FFF— upper RAM area used for buffers, flags, and configuration bytes.0x3FFE— modem I/O port address used for reading and writing serial data.0x400C,0x4010,0x4014— pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn/LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return viaRAND USR. - RST-based output: The native
RST 0x10(print character) andRST 0x28/RST 0x20(calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact. - Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found. - Bit-banged serial: The serial timing loop at
0x77F3uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"\A0
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\AF\BC\C2\C3
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"BC\AF\C9C\A8\A9\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FBEEE\EC\D8
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\CD\A9\CD\FFA\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"D\CA\D1\FE\CAC\FE\CAE\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"E\CA\FC\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F\CA\E8A\FE\CAD\FE\CA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\FE\CAC\FE\CA\FE\CA\E3A\FE\CA\A5\C3\E1\C3\E5\D5\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\D1\E1 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"\C5\D5\E5\CD\F5\E1\CD\C6\D1\C1\C2\B3\C9EE\BB\C8
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\E5DE\D7\E1\C3\C6
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EFEFECDF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EEFD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EFD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EEFEFE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EEC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EDDFEFE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EEF\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\F5B\CD\C6\CD\B1\CD\D7E\FEF\CD\FFA\FFF\E6
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CA\EBA\FEF\CD\C3\EBA\A9\FE\CA\CD\BB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
DC\C2ABC\C2\C9\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CA\B5D\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\CA\D0\FE\CA\E5\FEF\CA\E5\FE\D0D\FE\DAB\E6\DFF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\FE\FF\C8\EDB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CD\CD\F4BA\D7A\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"\CC\C3\B4\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
CA\A8\B7\CAA\A9C\A9A\C9C\B7\C8
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
ABB\C6\FE\D0E\FEF\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5"
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\CD\F5\A1\CD\C6\CD\BB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CA\E1\C3\B9FDDDFCCAD\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\C8\EDB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\C5\CD\AF\D7\CD\C1\CD\C3\B4\EDB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CD\AF\D7E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"\CD\F4B\C3\B1\EDBE\B9\C8
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\C5\CD\AF\D7\C1
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CDE\CD\F4B\C3\B4AB\FE\FF\C2B\C9\BD\C2AC\BC\C2AD\C0
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
ABDE\FFB\CD\BDE\FE\CA\FE\CA\A6\FE\C0\C2BE\C3\FF\FE\D0AE\FE\CA\C6\F5\CD\F1\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"C\CA\B9\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"E\CA\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F\CAE\FE\CA\A2\FE\CA\AA\FE\CA\AE\FE\CA\B2\FE\CA\B6\FE\CA\BA\FE\DA\BE\FEA\DA\C6\C9\AF\A9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\A8\C9\AF\C3A\CDE\C3
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\E1\C3\FC\E1\C3C\E1\C3
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\E1\C3C\E1\C3\FE\D8\FE\D0\C6\FE\CA\FFA\CD\B7\CA\F4\FEB\CA\F0\FEC\CA\F0B\FE\CA\F0D\FE\C2\F4\C3\FFF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\FBE\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C8A\CD\B7\CA\CDAA\FFF\E6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"\CA\FEF\C3\E1\E5\EEB\BD\C2\FEFAF\B7\C8A\CD\B7\C0\C3\E1\C3CE\FEF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5"
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\FFF\E6
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CAAA\FEFE\BA\CA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\AF\B8\C2\D5\CD\D1\AF\BA\CAAE\E5\D5\CD\D1\E1\C2D\AF\A9E\FEF\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AE\FE\CAE\C3E\A8E\EDB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CD\C3\B4E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F\FFF\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CD\D7\CDAE\D7\C9\E1A\A8\B7\C4E\CD\F4B\CD\F4BE\FEF\CDFB\C3C\AF\CD\F1\CD\F1\CD\F1E\CD\F1EA\CD\F1E\CD\F1\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\C2\F3\FFF\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AFECD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EABCDEFAEFEFEFECDF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
ABD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5"B
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
DF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5"A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\FF\FFB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FABCDEF\FFA\FFF\E6\CA\ED\AF\FFF\C3C\CDA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\BF\EBD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\EDC\CD\EDC\CDA\CD\E5B\C5\CD\EDC\C1\FE\DC\CEA\C3\CDA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\EB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C3
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AE\FF\CD\CDAEA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\BF\EBD\C3AE\FE\B8\CC\B5\D5\E5\CD\C6\E1\D1A\FFF\E6
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CAA\FEF\FE\C2\CD\A5C\FE\C2E\CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"B\AF\BB\C2\BA\C2\C3\C0CAADA\C0
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\CD\CE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CD\CEEA\CD\F9\CD\CEA\C9\D5
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\D1\E5\E7\FF\D2\C0C\EB\E1\CD\CEE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CDAA\FFF\E6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"\CA\CEAACA\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F\CA\EA\FEF\C9E
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\FEF\AFA\CD\F9\C3\CEAF\B7\C0A\FFF\E6
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EAA\FEF\E6F\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\C8\CDA\C3\F9\E5\D5\C5\CD\BB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\C1\D1\E1\C2\C0C\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\AFA\CD\D7 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\CD\F5EA\D7\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5"B\AF\BB\C0\BA\C0\E1A\C9C\B7\CAA\CD\CCCF\CD\CCC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AA\AF\BC\C2A\BD\C2A\C3A
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AAD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FFC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CD\EDC\CD\EDC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\CD\CE\C3C\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\CD\F5\B7A\CD\C6\CD\BB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\CAA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FF\EB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\D2C
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C3CEFF\E5\D5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\CD\F5AAF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"FA\D7\D1\E1\C9E\EC\CDFC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5"BC\C7C
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BE\FF\C9C\C3\D1
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"C
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7C\E5\CDE\E1B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"A\FE\C8\C7C\C3B
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5"\B8
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\EAA\C9C\B7\C8E\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"AC\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
FC\C7C\CDB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
E\AF\E4B
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7CE\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"\CAB\FE\CA\C9B\C7C\C2DB\C3B\AF\CABE\FF\E4B\AF\C5\CD\F4B\C1
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7CE\FE\CA\C9B\C2CB\C7C
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\C2B
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7CA\E4B\B7\CA\AFBE\C3\BBB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\C7CE\CD\F4B
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
ABCAB\C3B\AF\C5\CD\F4B\C1\C2\C9B
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\C2\C9B\AF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"AC\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C5\E5
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
AA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\E1\C1\C9A\C9C\B7\C8
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7C\E5\D5A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"AC\B7\CC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\CDBA itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"AC\B7\CC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\D1\E1\C7CA\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
BE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
B\C7C\E3\EB
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7C\F9\EB\E5\C3FC
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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-53132 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.7 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.5"E\ED\ED\FD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\E7
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EBD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
C\C2FC\CDA\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C9\CDFC\CDAC\C7CE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\FEFE\FF\C9C\CD\CCCF\CD\CCC\CDA\CD\CCC\CD\E5B\CD\F4BA\FE\DC\CEA\C3EC\CDA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\C7C\C3CC\CDAA\FFF\E6
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CA\A5CA\FEF\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D\CA\A5C\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\CA\A5C\E6F\C9\F9\C3C
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\CD\A5C\FE\DA\D6C\D6\D6F\CD\A5C\FE\DA\E9C\D6\D6\B0\C9F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F\E6
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\DA\FCC\C6\C6\CD\CE\E6
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\FE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
A\DA
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
CD\C6\C6\CD\CE\C9\CD\C3D\CD\DFD\CD\F6DE\CD\A9\AF\CD\FFA\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"D\CAD\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"E\CAD\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F\CAD\FE\CAC\C3DAF\B7\C2D
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\C3D\AFF\CD\BBD\C2D\C6\C3D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"A\CDD\CD\BBD\C2D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"A\CDD\C3DE\FE\C2DE\F6\C2FD\C9E\E6\DF\C2D\C9A\E7\FEA\CA\B1D\FEA\CA\B6DEA\E7\CD\BBD\C2DE\C3DEE\C3\A2DEA\C3\A2DA\FE\C9CEAF\B7\C2\D6DEF\C9\C9EA\FE\CA\F0DCF\C9\C9EA\E7\FEE\CAE\FEA\CA itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"EEF\C9E\C9\C9
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
ECFCF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
DEF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
D
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EEFDEDE\CBE\CD\A9E\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"AC\AF\ACF\CD\FFA\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"D\CAFF\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"E\CAF\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"F\CABF\FE\CAF\FE\CACF\FE\CAF\FE\CA\C5E\C3E\AF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"AC\C3C
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EFD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EFD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EFD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
EEFDEDE
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C3EF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\AA\C3EF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\D5\D5\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\D1DE\FE\CA\A6FE\CDF\C3CF
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\C3F
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\AA\C3F
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
\D5\D5\CDFCC\C7C\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\D1 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-53132 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.7 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.5"A\D5\CD\F9B\D1\CDF\C3FA\ACF\FE\C2\A0F\B8\CA\A5F\ACF\C9\E1\CD
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
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
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
F\C3E
Skip to content
ZComm
ZCommHere is a terminal communications program designed to operate with the Byte-Back MD2 modem, implemented almost entirely as machine code embedded in a REM statement at line 10. The program launches via a single RAND USR 16514 call in line 20, jumping into the Z80 code stored in the REM data. The machine code implements a full menu-driven interface with eleven options including conversational mode, sending and receiving programs and text data, transferring variable areas, upper memory functions, and configuration changes. The Z80 routines handle serial I/O at the hardware level, managing modem control registers and performing ASCII translation between the ZX81 character set and standard ASCII for transmission and display.
Program Analysis
Program Structure
The entire program consists of just two BASIC lines:
10 REM — contains approximately 2 KB of raw Z80 machine code, menu text strings, character translation tables, and configuration data embedded as REM data bytes.
20 RAND USR 16514 — transfers control to the machine code at address 16514 (0x4082), which is the start of the REM data payload (the REM statement header occupies the first few bytes of the line, so the code begins just after).
There are no other BASIC statements. All program logic, I/O handling, menus, and protocol routines are implemented in Z80 assembly language stored within the REM line.
Machine Code Entry and Memory Layout
The REM line begins at the standard BASIC program area. RAND USR 16514 (decimal) corresponds to address 0x4082, placing the code entry point two bytes into the REM payload (after the line number and length bytes). The machine code immediately sets up a custom stack pointer and jumps to the main dispatch loop.
Key addresses referenced in the disassembly include:
0x4039 / 0x4073 — internal jump and data pointers within the REM block.
0x7840–0x7FFF — upper RAM area used for buffers, flags, and configuration bytes.
0x3FFE — modem I/O port address used for reading and writing serial data.
0x400C, 0x4010, 0x4014 — pointers to display file and memory regions used during program transfer.
Main Menu System
Embedded ASCII strings inside the REM block define the main menu. The menu items, delimited by $ (0x24) terminators, offer eleven functions:
- CONVERSATIONAL MODE
- SEND A PROGRAM
- RECEIVE TEXT DATA
- RECEIVE A PROGRAM
- CHANGE CONFIGURATION
- SEND VARIABLE AREA
- RECEIVE VARIABLE AREA
- UPPER MEMORY FUNCTIONS
- SEND TEXT DATA
- ENTER TEXT DATA
- RETURN TO BASIC
Menu selection is dispatched via a chain of CP / JZ (Z80 FE xx CA addr) instructions, each comparing the received menu byte against a code (0x1D through 0x27) and jumping to the corresponding handler routine.
Serial I/O and Modem Handling
The code communicates with the MD2 modem through memory-mapped I/O at address 0x3FFE. Status and data bytes are read with LD A,(0x3FFE) sequences, and the code tests specific bits (notably bit 1 for receive-ready and bit 0 for transmit-ready) using AND 0x02 and AND 0x01 masks before reading or writing. A transmit routine at approximately 0x74FF polls the status register in a tight loop before outputting each byte.
The code manages a “connected” flag stored at 0x76A9 and a secondary flag at 0x76A8, toggling modem line states (XON/XOFF, 0x11/0x13) during data transfer sessions.
Character Set Translation
A significant portion of the REM data (visible as two 128-byte lookup tables near offset 0x77FB) provides bidirectional translation between the native character encoding and standard ASCII. Outgoing characters are looked up in one table before transmission; incoming ASCII bytes are mapped to the local character set on receipt. This allows the terminal to correctly exchange printable text with remote systems using standard ASCII.
Special incoming control codes are individually handled: 0x0D (carriage return), 0x0A (line feed), 0x08 and 0x7F (backspace/delete), and values ≥ 0x80 are range-checked before display.
Program and Variable Transfer Protocol
The send-program and receive-program routines iterate over the BASIC program area using the system variables at 0x400C (PROG) and 0x4010 / 0x4014 (E-LINE / VARS). Each byte is transmitted with a leading null handshake byte (AF D7 = XOR A / RST 0x10 equivalent sequences), and reception loops check for the 0x76 (HALT opcode, used as end-of-program sentinel in BASIC) terminator. A “PROGRAM MEMORY FULL” error string at 0x75A1 is displayed if the receive buffer is exhausted.
A “TRANSFER ERROR OCCURRED” string at 0x7AB7 and associated error-recovery code provide basic error reporting when a transfer fails mid-stream.
Configuration Submenu
The Change Configuration option presents its own submenu with four options: LOCAL ECHO (YES/NO), ASCII CASE (UP/DOWN), DATA TYPE (7BEP variants), and RETURN TO MAIN MENU. Configuration state is stored in flag bytes within the upper RAM area (e.g., 0x785F for echo, 0x77E7 for baud/stop-bit settings). The baud-rate and framing configuration modifies a delay constant at 0x77EC used by the bit-banged serial timing loop.
Upper Memory Functions Submenu
A further submenu at address 0x7ECB offers seven options for copying data to and from three defined memory “areas,” with area base addresses encoded as 16-bit constants (0x8000, 0xAA00, 0xD500) passed in the DE register before a common transfer dispatch routine. This allows the user to snapshot or restore sections of RAM using the modem link.
Notable Techniques
- REM-as-code: The entire application resides in a single REM line, a classic technique that keeps machine code safe from the BASIC line editor and NEW command while remaining contiguous in memory.
- Stack manipulation: The code saves and restores the Z80 stack pointer (
LD SP,nn / LD (nn),SP) to establish a local stack in upper RAM, keeping BASIC’s stack intact for clean return via RAND USR.
- RST-based output: The native
RST 0x10 (print character) and RST 0x28 / RST 0x20 (calculator / CALL HL) routines are used extensively for display output and indirect calls, keeping code compact.
- Inline string menus: Menu and error strings are embedded directly in the machine code stream, terminated with 0x24 (
$), and printed by a general-purpose string-output subroutine that advances a pointer until the sentinel is found.
- Bit-banged serial: The serial timing loop at
0x77F3 uses a counted inner loop (DJNZ) to generate bit-level timing, with the loop count loaded from a configuration byte to support multiple baud rates without hardware UART support.
Content
Source Code
10 REM \79\21\39\73\22\04\40\01\A0\40\11\39\73\21\74\0D\0A\12\03\13\2B\AF\BC\C2\92\40\C3\39\73\00\CD\1B\7C\AF\32\60\78\32\C9\7C\32\A8\76\32\A9\76\32\CD\79\2F\32\5B\78\32\61\78\3E\80\32\5E\78\3E\17\32\EC\77\21\D8\73\16\0B\CD\A9\73\CD\FF\74\3A\60\78\FE\1D\CA\D1\74\FE\20\CA\60\7C\FE\24\CA\85\7E\FE\1E\CA\FC\78\FE\1F\CA\E8\7A\FE\21\CA\13\7D\FE\22\CA\2D\79\FE\23\CA\99\7C\FE\25\CA\46\79\FE\26\CA\E3\7A\FE\27\CA\A5\73\C3\65\73\E1\C3\13\04\E5\D5\CD\2A\0A\D1\E1\01\01\08\C5\D5\E5\CD\F5\08\E1\23\CD\C6\73\D1\C1\04\15\C2\B3\73\C9\5E\3E\24\BB\C8\16\00\E5\21\8D\78\19\7E\D7\E1\23\C3\C6\73\31\2E\20\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\32\2E\20\20\53\45\4E\44\20\41\20\50\52\4F\47\52\41\4D\24\33\2E\20\20\52\45\43\45\49\56\45\20\54\45\58\54\20\44\41\54\41\24\34\2E\20\20\52\45\43\45\49\56\45\20\41\20\50\52\4F\47\52\41\4D\24\35\2E\20\20\43\48\41\4E\47\45\20\43\4F\4E\46\49\47\55\52\41\54\49\4F\4E\24\36\2E\20\20\53\45\4E\44\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\37\2E\20\20\52\45\43\45\49\56\45\20\56\41\52\49\41\42\4C\45\20\41\52\45\41\24\38\2E\20\20\55\50\50\45\52\20\4D\45\4D\4F\52\59\20\46\55\4E\43\54\49\4F\4E\53\24\39\2E\20\20\53\45\4E\44\20\54\45\58\54\20\44\41\54\41\24\41\2E\20\20\45\4E\54\45\52\20\54\45\58\54\20\44\41\54\41\24\42\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\42\41\53\49\43\20\24\CD\2A\0A\01\01\02\CD\F5\08\21\3B\78\CD\C6\73\CD\B1\77\CD\D7\77\3E\11\32\FE\3F\CD\FF\74\3A\FF\3F\E6\02\CA\EB\74\3A\FE\3F\CD\17\75\C3\EB\74\3A\A9\76\FE\15\CA\39\77\CD\BB\02\7D\3C\C2\04\76\3A\5B\78\3C\C2\23\76\C9\FE\0A\CA\B5\75\32\5D\78\FE\0D\CA\D0\75\FE\08\CA\E5\75\FE\7F\CA\E5\75\FE\80\D0\21\8D\78\FE\40\DA\3B\75\E6\DF\5F\16\00\19\7E\FE\FF\C8\32\60\78\ED\4B\39\40\0C\CD\18\09\CD\F4\7B\3A\60\78\D7\3A\39\40\FE\01\CC\60\75\C3\B4\77\CD\0E\0C\3A\A8\76\B7\CA\71\75\3A\A9\76\3C\32\A9\76\3A\C9\7C\B7\C8\2A\05\7B\23\22\05\7B\11\C6\FE\19\D0\3E\13\32\FE\3F\CD\2A\0A\01\06\0B\CD\F5\08\21\A1\75\CD\C6\73\CD\BB\02\2C\CA\96\75\E1\C3\B9\77\50\52\4F\47\52\41\4D\20\4D\45\4D\4F\52\59\20\46\55\4C\4C\24\3A\5D\78\FE\0D\C8\ED\4B\39\40\0C\C5\CD\18\09\AF\D7\CD\60\75\C1\CD\18\09\C3\B4\77\ED\4B\39\40\0C\CD\18\09\AF\D7\3E\01\32\60\78\CD\F4\7B\C3\B1\77\ED\4B\39\40\3E\20\B9\C8\0C\C5\CD\18\09\AF\D7\C1\0C\CD\18\09\3E\08\32\60\78\CD\F4\7B\C3\B4\77\3A\5B\78\FE\FF\C2\10\76\22\5B\78\C9\BD\C2\23\76\3A\5C\78\BC\C2\23\76\3A\61\78\3D\32\61\78\C0\2A\5B\78\44\4D\3E\FF\32\5B\78\32\61\78\CD\BD\07\7E\32\60\78\FE\74\CA\89\77\FE\79\CA\A6\77\FE\C0\C2\4B\76\3E\27\C3\FF\76\FE\80\D0\47\3A\5E\78\FE\80\78\CA\C6\76\F5\CD\89\77\F1\FE\1C\CA\B9\77\FE\1E\CA\95\76\FE\1F\CA\9E\76\FE\20\CA\A2\76\FE\21\CA\AA\76\FE\22\CA\AE\76\FE\23\CA\B2\76\FE\24\CA\B6\76\FE\25\CA\BA\76\FE\70\DA\BE\76\FE\7A\DA\C6\76\C9\AF\32\A9\76\2F\32\A8\76\C9\AF\C3\9A\76\CD\9E\76\C3\39\77\00\00\E1\C3\FC\78\E1\C3\60\7C\E1\C3\2D\79\E1\C3\99\7C\E1\C3\46\79\FE\26\D8\FE\40\D0\C6\52\FE\08\CA\FF\76\47\3A\CD\79\B7\78\CA\F4\76\06\27\FE\8B\CA\F0\76\06\23\FE\8C\CA\F0\76\06\5B\FE\90\CA\F0\76\06\5D\FE\91\C2\F4\76\78\C3\FF\76\5F\16\00\21\FB\77\19\7E\FE\00\C8\47\3A\CD\79\B7\CA\19\77\CD\14\7A\3A\FF\3F\E6\01\CA\07\77\78\32\FE\3F\C3\27\77\E1\E5\11\EE\74\7B\BD\C2\27\77\78\32\FE\3F\3A\5F\78\B7\C8\3A\CD\79\B7\C0\78\C3\17\75\E1\C3\3C\73\3E\13\32\FE\3F\16\00\21\84\77\01\00\10\3A\FF\3F\E6\02\CA\5A\77\3A\FE\3F\77\23\14\3E\05\BA\CA\60\77\0B\AF\B8\C2\46\77\D5\CD\69\08\D1\AF\BA\CA\7A\77\21\84\77\7E\E5\D5\CD\17\75\D1\E1\23\15\C2\6D\77\AF\32\A9\76\3E\11\32\FE\3F\C9\00\00\00\00\00\3A\5E\78\FE\80\CA\96\77\3E\80\C3\98\77\3E\A8\32\5E\78\ED\4B\39\40\0C\CD\18\09\C3\B4\77\3E\1F\32\FF\3F\CD\2A\0A\CD\D7\77\CD\60\75\3A\5E\78\D7\C9\E1\3A\A8\76\B7\C4\39\77\3E\76\32\60\78\CD\F4\7B\CD\F4\7B\3E\13\32\FE\3F\CD\3F\7B\C3\3C\73\AF\CD\F1\77\CD\F1\77\CD\F1\77\3E\40\CD\F1\77\3E\7A\CD\F1\77\3E\17\CD\F1\77\C9\06\0C\05\C2\F3\77\32\FF\3F\C9\20\00\00\00\00\00\00\00\00\00\00\22\40\24\3A\3F\28\29\3E\3C\3D\2B\2D\2A\2F\3B\2C\2E\30\31\32\33\34\35\36\37\38\39\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\50\51\52\53\54\55\56\57\58\59\5A\4E\4F\57\20\49\4E\20\43\4F\4E\56\45\52\53\41\54\49\4F\4E\41\4C\20\4D\4F\44\45\24\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\23\0A\5B\5D\00\1B\0D\7F\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\FF\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\FF\FF\FF\FF\FF\00\FF\0B\8C\0D\FF\FF\8B\10\11\17\15\1A\16\1B\18\1C\1D\1E\1F\20\21\22\23\24\25\0E\19\13\14\12\0F\0C\26\27\28\29\2A\2B\2C\2D\2E\2F\30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\90\98\91\FF\96\3A\FF\3F\E6\04\CA\ED\78\AF\32\FF\3F\C3\3C\73\CD\23\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\00\00\00\00\00\43\CD\ED\7C\42\CD\ED\7C\CD\43\7A\46\CD\E5\7B\C5\CD\ED\7C\C1\78\FE\76\DC\CE\7A\23\C3\17\79\CD\23\7A\2A\10\40\7C\2F\57\7D\2F\5F\13\2A\14\40\19\EB\13\2A\10\40\C3\0A\79\3E\FF\32\CD\79\CD\23\7A\3E\20\32\22\7A\2A\0C\40\11\84\BF\19\EB\21\7D\40\C3\8A\79\7E\FE\B8\CC\B5\79\D5\E5\CD\C6\76\E1\D1\3A\FF\3F\E6\02\CA\86\79\3A\FE\3F\FE\13\C2\86\79\CD\A5\7C\FE\11\C2\7E\79\CD\97\79\23\1B\AF\BB\C2\61\79\BA\C2\61\79\C3\C0\7C\3A\22\7A\3D\32\22\7A\C0\06\0D\CD\CE\79\06\0A\CD\CE\79\3E\20\32\22\7A\CD\F9\79\CD\CE\7A\C9\D5\11\19\00\19\D1\E5\21\E7\FF\19\D2\C0\7C\EB\E1\06\08\CD\CE\79\3E\01\C9\00\CD\14\7A\3A\FF\3F\E6\01\CA\CE\79\3A\22\7A\3C\32\22\7A\FE\1F\CA\EA\79\78\32\FE\3F\C9\3E\0D\32\FE\3F\AF\32\22\7A\CD\F9\79\C3\CE\79\3A\5F\78\B7\C0\3A\FF\3F\E6\02\CA\0E\7A\3A\FE\3F\E6\7F\FE\0D\C8\CD\14\7A\C3\F9\79\E5\D5\C5\CD\BB\02\2C\C1\D1\E1\C2\C0\7C\C9\00\CD\2A\0A\21\00\00\22\41\7A\AF\32\22\7A\CD\D7\77\01\0F\0B\CD\F5\08\3E\80\32\40\7A\D7\C9\00\00\00\1B\AF\BB\C0\BA\C0\E1\3A\C9\7C\B7\CA\69\7A\CD\CC\7C\5F\CD\CC\7C\57\2A\41\7A\19\AF\BC\C2\83\7A\BD\C2\83\7A\C3\99\7A\2A\41\7A\7D\2F\6F\7C\2F\67\23\45\CD\ED\7C\44\CD\ED\7C\06\0D\CD\CE\79\C3\3C\73\CD\2A\0A\01\01\0B\CD\F5\08\21\B7\7A\CD\C6\73\CD\BB\02\2C\CA\92\7A\2A\10\40\23\23\7C\2F\67\7D\2F\6F\23\EB\2A\14\40\19\D2\3C\73\2A\10\40\23\22\10\40\C3\3C\73\54\52\41\4E\53\46\45\52\20\45\52\52\4F\52\20\4F\43\43\55\52\45\44\24\E5\D5\01\0F\0B\CD\F5\08\3A\40\7A\17\3F\1F\32\40\7A\D7\D1\E1\C9\3E\10\32\EC\77\CD\3F\7C\21\00\01\22\22\7B\21\7C\40\22\C7\7C\21\00\00\22\05\7B\3E\FF\32\C9\7C\C3\D1\74\00\00\01\1C\00\2A\C7\7C\E5\CD\9E\09\E1\11\22\7B\1A\FE\24\C8\23\77\13\22\C7\7C\C3\15\7B\00\01\B8\02\EA\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\24\3A\C9\7C\B7\C8\3E\FF\32\1A\7C\CD\23\0F\21\7C\40\22\C7\7C\CD\07\7B\0E\15\06\20\AF\32\E4\7B\2A\C7\7C\23\7E\FE\01\CA\76\7B\FE\76\CA\C9\7B\22\C7\7C\05\C2\5D\7B\C3\98\7B\AF\77\05\CA\98\7B\3E\FF\32\E4\7B\AF\32\60\78\C5\CD\F4\7B\C1\2A\C7\7C\23\7E\FE\76\CA\C9\7B\05\C2\7C\7B\22\C7\7C\0D\C2\57\7B\2A\C7\7C\3A\E4\7B\B7\CA\AF\7B\3E\76\77\C3\BB\7B\2B\22\C7\7C\3E\76\32\60\78\CD\F4\7B\2A\22\7B\55\5C\13\6A\63\22\22\7B\C3\52\7B\AF\32\60\78\C5\CD\F4\7B\C1\05\C2\C9\7B\06\20\0D\C2\C9\7B\AF\32\1A\7C\CD\2B\0F\C9\00\C5\E5\2A\41\7A\48\06\00\09\22\41\7A\E1\C1\C9\3A\C9\7C\B7\C8\2A\C7\7C\E5\D5\3A\1A\7C\B7\CC\23\0F\CD\9B\09\3A\1A\7C\B7\CC\2B\0F\D1\E1\23\22\C7\7C\3A\60\78\77\C9\00\21\39\73\2B\36\3E\2B\22\C7\7C\E3\EB\2A\C7\7C\F9\EB\E5\C3\3F\7C\2B\2B\22\02\40\3E\1E\ED\47\ED\56\FD\21\00\40\CD\E7\02\3E\40\32\3B\40\21\7D\40\22\0C\40\06\19\36\76\23\05\C2\4F\7C\22\10\40\CD\9A\14\CD\07\02\C9\CD\3F\7C\CD\23\7A\21\7C\40\22\C7\7C\3E\0D\32\FE\3F\3E\FF\32\C9\7C\CD\CC\7C\5F\CD\CC\7C\57\CD\43\7A\CD\CC\7C\32\60\78\47\CD\E5\7B\CD\F4\7B\3A\60\78\FE\76\DC\CE\7A\C3\7E\7C\CD\23\7A\2A\10\40\22\C7\7C\C3\6C\7C\CD\14\7A\3A\FF\3F\E6\02\CA\A5\7C\3A\FE\3F\FE\0D\CA\A5\7C\FE\0A\CA\A5\7C\E6\7F\C9\21\37\73\F9\C3\3C\73\00\00\00\00\00\CD\A5\7C\FE\40\DA\D6\7C\D6\07\D6\30\37\3F\17\17\17\17\47\CD\A5\7C\FE\40\DA\E9\7C\D6\07\D6\30\B0\C9\78\4F\1F\1F\1F\1F\E6\0F\FE\0A\DA\FC\7C\C6\07\C6\30\47\CD\CE\79\79\E6\0F\FE\0A\DA\0C\7D\C6\07\C6\30\47\CD\CE\79\C9\CD\C3\7D\CD\DF\7D\CD\F6\7D\21\29\7E\16\04\CD\A9\73\AF\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\45\7D\FE\1E\CA\60\7D\FE\1F\CA\93\7D\FE\20\CA\3C\73\C3\28\7D\3A\5F\78\B7\C2\50\7D\2F\C3\51\7D\AF\32\5F\78\CD\BB\7D\C2\13\7D\32\C6\45\C3\13\7D\06\1A\21\21\78\CD\79\7D\CD\BB\7D\C2\13\7D\06\1A\21\88\45\CD\79\7D\C3\13\7D\7E\FE\41\C2\89\7D\7E\F6\20\77\23\05\C2\7F\7D\C9\7E\E6\DF\77\23\05\C2\89\7D\C9\3A\E7\77\FE\5A\CA\B1\7D\FE\7A\CA\B6\7D\3E\7A\32\E7\77\CD\BB\7D\C2\13\7D\32\4E\45\C3\13\7D\3E\6E\C3\A2\7D\3E\5A\C3\A2\7D\47\3A\82\40\FE\79\78\C9\21\3C\7E\3A\5F\78\B7\C2\D6\7D\36\20\23\36\4E\23\36\4F\C9\36\59\23\36\45\23\36\53\C9\21\53\7E\3A\21\78\FE\41\CA\F0\7D\36\4C\23\36\4F\C9\36\55\23\36\50\C9\21\67\7E\3A\E7\77\FE\6E\CA\12\7E\FE\7A\CA\1E\7E\36\37\23\36\42\23\36\4F\23\36\50\C9\36\38\23\36\42\23\36\4E\23\36\50\C9\36\37\23\36\42\23\36\45\23\36\50\C9\31\2E\20\20\4C\4F\43\41\4C\20\45\43\48\4F\20\2D\20\20\20\4E\4F\24\32\2E\20\20\41\53\43\49\49\20\43\41\53\45\20\2D\20\20\20\55\50\24\33\2E\20\20\44\41\54\41\20\20\54\59\50\45\20\2D\20\37\42\45\50\24\34\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\21\CB\7E\16\07\CD\A9\73\3E\FF\32\1A\7C\AF\32\AC\7F\32\60\78\CD\FF\74\3A\60\78\FE\1D\CA\3F\7F\FE\1E\CA\45\7F\FE\1F\CA\4B\7F\FE\20\CA\66\7F\FE\21\CA\6C\7F\FE\22\CA\72\7F\FE\23\CA\C5\7E\C3\99\7E\AF\32\1A\7C\C3\3C\73\31\2E\20\20\54\4F\20\41\52\45\41\20\31\24\32\2E\20\20\54\4F\20\41\52\45\41\20\32\24\33\2E\20\20\54\4F\20\41\52\45\41\20\33\24\34\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\31\24\35\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\32\24\36\2E\20\20\46\52\4F\4D\20\41\52\45\41\20\33\24\37\2E\20\20\52\45\54\55\52\4E\20\54\4F\20\4D\41\49\4E\20\4D\45\4E\55\20\24\11\00\80\C3\4E\7F\11\00\AA\C3\4E\7F\11\00\D5\D5\CD\23\0F\D1\21\7D\40\7E\FE\76\CA\A6\7F\7E\12\CD\93\7F\23\13\C3\5C\7F\11\00\80\C3\75\7F\11\00\AA\C3\75\7F\11\00\D5\D5\CD\3F\7C\21\7C\40\22\C7\7C\CD\23\0F\D1\1A\32\60\78\D5\CD\F9\7B\D1\CD\93\7F\13\C3\83\7F\47\3A\AC\7F\FE\76\C2\A0\7F\B8\CA\A5\7F\78\32\AC\7F\C9\E1\CD\2B\0F\C3\85\7E\00
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
People
No people associated with this content.
20 RAND USR 16514
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.







