--- title: "tape2tape" id: 70972 type: "computer_media" slug: "tape2tape" url: "http://localhost/computer_media/tape2tape/" markdown_url: "http://localhost/computer_media/tape2tape.md" published_at: "2026-08-24T23:52:36+00:00" modified_at: "2026-08-24T23:53:34+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/tape2tape.png" alt: "tape2tape screen" excerpt: "A clever 26-byte machine code routine turns the computer into a signal relay between two tape decks, cleaning up copies on the fly." 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: "Cameron Hayne" slug: "cameron-hayne" taxonomy: "indiv" url: "http://localhost/indiv/cameron-hayne/" genre: - name: "Tape" slug: "tape" taxonomy: "genre" url: "http://localhost/type/tape/" media_type: "Program" programmers: - name: "Cameron Hayne" slug: "cameron-hayne" taxonomy: "indiv" url: "http://localhost/indiv/cameron-hayne/" download_url: "https://archive.org/download/timex-sinclair-software-archive/tape2tape%20%281985%29%28Hayne%2C%20Cameron%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "1985" images: - url: "http://localhost/wp-content/uploads/2026/08/tape2tape.png" alt: "tape2tape screen" media_type_tags: "Tape" --- # tape2tape Tape2Tape uses a short machine code routine to relay a tape signal through the computer, acting as an intermediary between two cassette recorders to produce a cleaner copy. The BASIC loader POKEs 26 bytes of Z80 machine code into memory starting at address 23296, then prompts the user to connect the EAR output of the source deck to the computer’s EAR jack and the computer’s MIC output to the destination deck’s MIC jack. The machine code reads the EAR port and writes the conditioned signal back out through the MIC port in a tight loop, with the Z80’s interrupt flag manipulated (DI/EI via bytes 243 and 251) to prevent interference during the relay. Execution begins via RANDOMIZE USR after the user presses ENTER, and BREAK is used to halt the process. *** ### Program Structure The program is compact at just five active lines plus a `SAVE` statement: 1. `10` — REM header (title and authorship) 2. `20` — Sets base address `A=23296` for the machine code block 3. `30` — POKEs 26 bytes of Z80 machine code and contains the `DATA` statement inline 4. `40`–`50` — User instructions printed to screen 5. `60` — Waits for ENTER (`PAUSE 0`) then launches the routine with `RANDOMIZE USR A` 6. `70` — Saves the program with `LINE 1` auto-run ### Machine Code Routine The 26 bytes POKEd starting at address 23296 disassemble as a tight Z80 loop. The DATA values are: `243,1,254,127,17,2,14,237,120,31,48,12,230,32,40,4,237,81,24,243,237,89,24,239,251,201` | Bytes (hex) | Mnemonic | Notes | | --- | --- | --- | | F3 | DI | Disable interrupts for clean timing | | 01 FE 7F | LD BC, 7FFEh | Load EAR port address into BC | | 11 02 0E | LD DE, 0E02h | MIC bit pattern preloaded into DE | | ED 78 | IN A, (C) | Read EAR port (port 0x7FFE) | | 1F | RRA | Rotate right — moves EAR bit into carry | | 30 0C | JR NC, +12 | Branch if EAR bit was 0 | | E6 20 | AND 20h | Isolate MIC bit | | 28 04 | JR Z, +4 | Conditional branch on MIC state | | ED 51 | OUT (C), D | Output MIC high via D register | | 18 F3 | JR -13 | Loop back | | ED 59 | OUT (C), E | Output MIC low via E register | | 18 EF | JR -17 | Loop back | | FB | EI | Re-enable interrupts (only on clean exit) | | C9 | RET | Return to BASIC | The routine reads the EAR input bit continuously, conditions it, and drives the MIC output bit accordingly. Because it runs in a tight loop with interrupts disabled (`DI` at entry), there is no interrupt-induced jitter to corrupt the relay timing. The `EI`/`RET` tail is effectively unreachable in normal operation — the loop is exited only by pressing BREAK, which causes an NMI or maskable interrupt depending on hardware, returning control to BASIC. ### Address Choice Address 23296 (0x5B00) is noted in the `REM` comment as arbitrary. This region falls in the ZX81/TS1000 system RAM area above the display file but below typical BASIC program space, making it a reasonable scratchpad for short machine code. The comment explicitly acknowledges the address can be relocated, which is good practice since the routine contains no absolute addresses — all branches are relative (`JR`). ### Notable BASIC Techniques - `DATA` is placed on the same line as the `FOR`/`READ`/`POKE` loop (`30`), minimizing line overhead and keeping the loader self-contained. - `PAUSE 0` followed by `RANDOMIZE USR A` on line `60` is the standard idiom for waiting for ENTER before launching machine code. - The `SAVE "tape2tape" LINE 1` on line `70` saves the program so that it auto-runs from line 1 on next load, though line 1 is a `REM` — effective auto-run will fall through to line 20. ### Potential Anomalies - The `EI` and `RET` bytes at the end of the machine code are only reached if the loop exits cleanly, which it does not under normal BREAK conditions. They are harmless but essentially dead code in practice. - The machine code loop does not implement any hysteresis or debounce beyond the single-bit EAR read, so the quality improvement over a direct cable connection depends on the digital thresholding inherent in the EAR input circuitry rather than any additional filtering in the routine itself. ## Source Code ``` 10 REM TAPE2TAPE © 1985 Cameron Hayne 20 LET A=23296:REM this address can be anything 30 FOR I=A TO A+25:READ B:POKE I,B:NEXT I:DATA 243,1,254,127,17,2,14,237,120,31,48,12,230,32,40,4,237,81,24,243,237,89,24,239,251,201 40 CLS :PRINT " THIS PROGRAM USES THE COMPUTER AS AN INTERMEDIARY BETWEEN TWO TAPE RECORDERS TO CLEAN UP THE SIGNAL WHEN MAKING A TAPE TO TAPE COPY. PLUG THE EAR OUTPUT OF #1 INTO THE EAR JACK OF THE COMPUTER. PLUG THE MIC OUTPUT OF THE COMPUTER INTO THE MIC JACK OF #2. PUT THE ORIGINAL TAPE IN #1 AND A NEW TAPE IN #2."'' 50 PRINT "START #2 ON RECORD"'"THEN PRESS ""ENTER"""'"AND THEN START #1 ON PLAY"'''"PRESS BREAK TO STOP " 60 PAUSE 0:RANDOMIZE USR A 70 SAVE "tape2tape" LINE 1 ```