tape2tape

Developer(s): Cameron Hayne
Date: 1985
Type: Program
Platform(s): TS 2068
Tags: Tape

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. 4050 — 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)MnemonicNotes
F3DIDisable interrupts for clean timing
01 FE 7FLD BC, 7FFEhLoad EAR port address into BC
11 02 0ELD DE, 0E02hMIC bit pattern preloaded into DE
ED 78IN A, (C)Read EAR port (port 0x7FFE)
1FRRARotate right — moves EAR bit into carry
30 0CJR NC, +12Branch if EAR bit was 0
E6 20AND 20hIsolate MIC bit
28 04JR Z, +4Conditional branch on MIC state
ED 51OUT (C), DOutput MIC high via D register
18 F3JR -13Loop back
ED 59OUT (C), EOutput MIC low via E register
18 EFJR -17Loop back
FBEIRe-enable interrupts (only on clean exit)
C9RETReturn 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.

Image Gallery

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

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.