--- title: "SEND VARS" id: 54580 type: "computer_media" slug: "send-vars" url: "http://localhost/computer_media/send-vars/" markdown_url: "http://localhost/computer_media/send-vars.md" published_at: "2024-06-02T17:50:46+00:00" modified_at: "2026-03-30T21:45:18+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A modem utility that hides and restores BASIC variables and machine code by embedding callable routines directly inside a REM statement for over-the-wire transfer." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "David Hoshor" slug: "david-hoshor" taxonomy: "indiv" url: "http://localhost/indiv/david-hoshor/" genre: - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_contents: - id: 51214 title: "CATS Library Tape 8" type: "computer_media" url: "http://localhost/computer_media/cats-library-tape-8/" media_type: "Program" programmers: - name: "David Hoshor" slug: "david-hoshor" taxonomy: "indiv" url: "http://localhost/indiv/david-hoshor/" mediadate: "198x" media_type_tags: "Utility" --- # SEND VARS SEND-VARS is a utility designed to work alongside the MTERM modem program, allowing machine code and BASIC variables to be transmitted over a modem link on the TS2068. The program uses direct memory POKEs to addresses in the 26700s range to invoke small machine code routines that manipulate the variable area, converting it to a modem-transmittable form and later restoring it. Line 2 accepts a code length and source address, computes high and low bytes via integer arithmetic, and stores them before calling USR 26735 to copy the target block into the string variable `x$`. Lines 3 and 4 use `RANDOMIZE USR` calls to hide and reveal variables respectively, a technique that temporarily makes the BASIC variable area invisible to the interpreter. Line 1 contains an embedded machine code payload stored within a REM statement, a common approach for self-contained TS2068 utilities that need resident routines without requiring a separate binary file. *** ## Program Analysis ### Program Structure The program is a compact eight-line utility. Lines 1 and 7–8 are `REM` statements; line 1 holds the embedded machine code payload, while lines 7 and 8 provide user documentation. Lines 2–6 are the operational entry points, each intended to be invoked manually with a `GO TO` command rather than run sequentially. | Line | Purpose | | --- | --- | | 1 | REM containing machine code routines at fixed USR addresses | | 2 | Entry point: capture code from high memory into `x$` | | 3 | Entry point: hide variables (convert to sendable form) | | 4 | Entry point: reveal/restore variables | | 5 | Entry point: replace code back into high memory from `x$` | | 6 | Safety `STOP` to prevent fall-through | | 7–8 | User documentation in REM blocks | ### Machine Code in the REM Statement Line 1 is a `REM` statement whose body encodes a series of machine code routines. The BASIC interpreter ignores REM content at runtime, making it a safe container for arbitrary binary data. The routines are accessed via `USR` with hard-coded addresses in the 26715–26777 range, which point into the body of this REM line in memory. This is a well-established technique for embedding self-contained machine code in a BASIC program without a separate binary file. The specific USR entry points used are: - `USR 26715` — hide variables (called from line 3) - `USR 26728` — reveal/restore variables (called from line 4) - `USR 26735` — copy source code block into `x$` (called from line 2) - `USR 26754` — write `x$` contents back to high memory (called from line 5) - `POKE 26777` / `POKE 26776` — pass parameters (high byte and low byte of source address) to the machine code ### Address Calculation Technique Line 2 splits the 16-bit source address into its high and low bytes using a standard BASIC idiom: `INT(sad/256)` yields the high byte, and `256*(sad/256-INT(sad/256))` recovers the fractional part and scales it back to give the low byte. These are then POKEd into fixed locations (26777 and 26776 respectively) so the machine code routine can read them as a two-byte address parameter. ### Variable Hiding Mechanism The hide/reveal pair at lines 3 and 4 exploits the BASIC system variables that record the start or length of the variable area. By calling `RANDOMIZE USR 26715`, the machine code presumably moves or masks a system pointer so the interpreter no longer finds or displays the variable block — making the variables invisible to a casual `LIST` or inspection. `RANDOMIZE` is used rather than a plain `USR` expression to discard the return value cleanly. The subsequent `STOP` on each line prevents accidental fall-through. ### The MERGE Workflow The intended usage described in lines 7–8 is to `MERGE` this utility into an already-loaded BASIC program. Because `MERGE` adds lines without erasing existing ones, the target program’s lines and variables remain intact while the utility’s lines (1–8) are added. The user then executes specific `GO TO` targets (3, 4, or 2) by hand to trigger each phase of the encode/send/decode cycle. ### Notable Techniques and Idioms - Machine code stored in a `REM` statement body, accessed by absolute `USR` address — requires the program to always load at the same memory location. - `RANDOMIZE USR n` used to call machine code and suppress the return value without a `LET` assignment. - High/low byte decomposition of a 16-bit address performed entirely in BASIC floating-point arithmetic. - `DIM x$(col)` allocates a string of exactly the required length to hold the binary code payload. - `LET x$(1)=CHR$ USR 26735` — the assignment to `x$(1)` is a side-effect trigger; the machine code routine uses the pre-POKEd parameters and fills `x$` in bulk, returning an irrelevant character to satisfy the BASIC expression. - Line 5 uses `IF sad AND col` as a guard to ensure both parameters were set before attempting to replace code, providing minimal input validation. ### Potential Issues The machine code entry points are hard-coded absolute addresses. If the program is loaded at a different memory location (e.g., due to a different BASIC program preceding it in memory), all `USR` calls will point to wrong or garbage memory, causing a crash. The utility is therefore fragile and must be loaded fresh or MERGEd in a controlled way that guarantees its position in RAM. No bounds checking is performed on the user-supplied `col` or `sad` values before the POKEs and USR calls are made. ## Source Code ``` 1 REM *K\\"\gh*Y\\"K\\<>*\gh"K\\<>*M\\T]+F+N*\ih GO SUB VAL *M\\N<>*M\\ RESTORE +F+N LLIST GO SUB [\ih GO SUB VAL *M\\N<>\d| OPEN # 2 INPUT "Code length? ";col: INPUT "Source address? ";sad: DIM x$(col): POKE 26777,INT (sad/256): POKE 26776,256*(sad/256-INT (sad/256)): LET x$(1)=CHR$ USR 26735: REM line puts code in x$ 3 RANDOMIZE USR 26715: STOP : REM line hides variables 4 RANDOMIZE USR 26728: STOP : REM line reveals variables 5 IF sad AND col THEN LET x$(1)=CHR$ USR 26754: STOP : REM line replaces code 6 STOP 7 REM SEND-VARS An MTERM MODEM program utility \* 1984 David Hoshor TO USE SEND-VARS WITH A BASIC PROGRAM, LOAD BASIC PROGRAM AND/OR VARIABLES THAT YOU WANT TO SEND BY MTERM MODEM PROGRAM. MERGE SEND-VARS. ENTER: GO TO 3.THE VARIABLES WILL BE CONVERTED TO A MODEM SENDABLE FORM. WHEN THE RECIPIENT GETS THE PROGRAM, HE SHOULD ENTER: GO TO 4. THE VARIABLES WILL NOW BE RESTORED. 8 REM TO SEND CODE FROM HIGH MEMORY ENTER: GO TO 2. YOU WILL BE PROMPTED FOR LENGTH AND ADDRESS OF CODE. THE CODE WILL BE MOVED INTO X$ AND VARIABLES CONVERTED TO SENDABLE FORM. WHEN RECEIVED THE RECIPIENT MUSTENTER: GO TO 4 THE CODE IN X$ WILL BE REPLACED IN HIGH MEMORY. ```