ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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



ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B\AF\BC\C2\C3

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FBEEE\EC\D8

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\FE\CAC\FE\CA\FE\CA\E3A\FE\CA\A5\C3\E1\C3\E5\D5\CD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\E5DE\D7\E1\C3\C6

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EFEFECDF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EEFD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EFD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EEFEFE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EEC

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EC

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EDDFEFE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EEF\CD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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"

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\CD\F5B\CD\C6\CD\B1\CD\D7E\FEF\CD\FFA\FFF\E6

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\CA\EBA\FEF\CD\C3\EBA\A9\FE\CA\CD\BB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
DC\C2ABC\C2\C9\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\CA\B5D\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\CA\D0\FE\CA\E5\FEF\CA\E5\FE\D0D\FE\DAB\E6\DFF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E\FE\FF\C8\EDB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
CA\A8\B7\CAA\A9C\A9A\C9C\B7\C8

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
ABB\C6\FE\D0E\FEF\CD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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"

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B\CD\F5\A1\CD\C6\CD\BB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\CA\E1\C3\B9FDDDFCCAD\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\C8\EDB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\C5\CD\AF\D7\CD\C1\CD\C3\B4\EDB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\C5\CD\AF\D7\C1

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\CDE\CD\F4B\C3\B4AB\FE\FF\C2B\C9\BD\C2AC\BC\C2AD\C0

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F\A8\C9\AF\C3A\CDE\C3

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\E1\C3\FC\E1\C3C\E1\C3

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\FBE\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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"

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\FFF\E6

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\CAAA\FEFE\BA\CA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B\AF\B8\C2\D5\CD\D1\AF\BA\CAAE\E5\D5\CD\D1\E1\C2D\AF\A9E\FEF\C9

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
AE\FE\CAE\C3E\A8E\EDB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\C2\F3\FFF\C9

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
AFECD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EABCDEFAEFEFEFECDF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
ABD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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"

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\FF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
BC

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FABCDEF\FFA\FFF\E6\CA\ED\AF\FFF\C3C\CDA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\BF\EBD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\CD\EDC\CD\EDC\CDA\CD\E5B\C5\CD\EDC\C1\FE\DC\CEA\C3\CDA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
AC

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\EB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\C3

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
AE\FF\CD\CDAEA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\BF\EBD\C3AE\FE\B8\CC\B5\D5\E5\CD\C6\E1\D1A\FFF\E6

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\CD\CE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\CD\CEEA\CD\F9\CD\CEA\C9\D5

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\FEF\AFA\CD\F9\C3\CEAF\B7\C0A\FFF\E6

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\CA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EAA\FEF\E6F\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\C8\CDA\C3\F9\E5\D5\C5\CD\BB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\C1\D1\E1\C2\C0C\C9

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\CD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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"

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B\CD\F5EA\D7\C9

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
AA\AF\BC\C2A\BD\C2A\C3A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
AAD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FFC

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F\CD\EDC\CD\EDC

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\CD\CE\C3C\CD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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"

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B\CD\F5\B7A\CD\C6\CD\BB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\CAA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
AC

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FF\EB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\D2C

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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"

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
BE\FF\C9C\C3\D1

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
FC\C7C\CDB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E\AF\E4B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\C7CE\FE\CA\C9B\C2CB\C7C

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\C2B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\C7CA\E4B\B7\CA\AFBE\C3\BBB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B\C7CE\CD\F4B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
ABCAB\C3B\AF\C5\CD\F4B\C1\C2\C9B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F\C9

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\C5\E5

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
AA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\E1\C1\C9A\C9C\B7\C8

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F\D1\E1\C7CA\C9

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
BE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B\C7C\E3\EB

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\C7C\F9\EB\E5\C3FC

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\CD\E7

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EBD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
C\C2FC\CDA\CD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\C9\CDFC\CDAC\C7CE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\FEFE\FF\C9C\CD\CCCF\CD\CCC\CDA\CD\CCC\CD\E5B\CD\F4BA\FE\DC\CEA\C3EC\CDA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\C7C\C3CC\CDAA\FFF\E6

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\CA\A5CA\FEF\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D\CA\A5C\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\CA\A5C\E6F\C9\F9\C3C

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\DA\FCC\C6\C6\CD\CE\E6

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F\FE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
A\DA

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
ECFCF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
DEF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
E

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
D

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EFD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EFD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EFD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
EEFDEDE

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\C3EF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\AA\C3EF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\D5\D5\CD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F\D1DE\FE\CA\A6FE\CDF\C3CF

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\C3F

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\AA\C3F

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
\D5\D5\CDFCC\C7C\CD

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
B

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
F\C3E

ZComm

Products: MD-2B Modem
Date: 1984
Type: Cassette
Platform(s): TS 1000
Tags: Terminal

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.
  • 0x78400x7FFF — 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:

  1. CONVERSATIONAL MODE
  2. SEND A PROGRAM
  3. RECEIVE TEXT DATA
  4. RECEIVE A PROGRAM
  5. CHANGE CONFIGURATION
  6. SEND VARIABLE AREA
  7. RECEIVE VARIABLE AREA
  8. UPPER MEMORY FUNCTIONS
  9. SEND TEXT DATA
  10. ENTER TEXT DATA
  11. 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

Appears On

Related Products

Works with any amount of memory on the 1000; with 64K will store 60 screens. Terminal software included. Prints to...

Related Articles

What you see on the left is a series of “screens” which I dumped to my printer while signed on...
Review of the Byte-Back modem for the TS1000.
Describes accessing various online services with a TS1000 and Byte-Back MD-2 modem.
Review of Byte-Back MD-1 and MD-2 modems.

Related Content

Image Gallery

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.

Scroll to Top
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.

Scroll to Top