[img] Tape Routines without BREAK error
 MDFS::Info.Comp.Spectrum.Code.Tape.tape/htm Search  

The Spectrum ROM tape routines provide two main entry points - SA_BYTES and LD_BYTES. These two routines
check for SPACE being pressed and generate an error if pressed. It is possible to call the tape routines and have
them return instead of generate an error. Each routine starts by stacking ERRSP, and setting it to the calling code
to return it it. Annoyingly, there is no way of stopping the tape routines from aborting when just SPACE is pressed
instead of SHIFT+SPACE.

Load data

; TAPELD - Load block from tape
; -----------------------------
; On entry: A =block type
;           IX=start
;           DE=length
;           CS=load, CC=verify
; On exit:   C=Ok
;           NC=Block not loaded or Timeout or BREAK
ERRSP	EQU	23613
TAPELD	LD	HL,(ERRSP)	; Save error handler
	PUSH	HL
	CALL	TAPEL2
	JR	TAPERET
TAPEL2	LD	(ERRSP),SP
	JP	&0556		; Call LD_BYTES

Save data

; TAPESV - Save block to tape
; ---------------------------
; On entry: A =block type
;           IX=start
;           DE=length
; On exit:   C=Ok
;           NC=BREAK
TAPESV	LD	HL,(ERRSP)	; Save error handler
	PUSH	HL
	CALL	TAPES2
TAPERET	POP	HL
	LD	(ERRSP),HL
	RET
TAPES2	LD	(ERRSP),SP
	JP	&04C2		; Call SV_BYTES

Calling from Basic

The routines return the status in the flags, when calling from Basic the only result returned is the contents of the
BC register. The code can be rewritten to be callable from Basic and return the result. Source code: tape.src (L).


REM Create the machine code:
FOR a=23300 TO 23390:READ b:POKE a,b:NEXT a
DATA 195,42,91,195,37,91,195,18,91,205,84,91,24,3,205,75,91
DATA 42,61,92,229,205,30,91,24,23,237,115,61,92,195,194,4
DATA 205,84,91,24,3,205,75,91,42,61,92,229,55,205,66,91,225
DATA 34,61,92,1,0,0,216,12,205,84,31,208,12,201,237,115,61
DATA 92,195,86,5,221,33,239,91,17,17,0,175,201,221,42,252,91
DATA 237,91,250,91,62,255,201

REM Load the next file header to 23535-23551:
LET bc=USR 23300

REM Load next data block its own address:
LET bc=USR 23303

REM Load next data block to address 'start':
POKE 23549,INT(start/256):POKE 23548,start-256*PEEK23549
LET bc=USR 23303

REM Save a file header from 23535-23551:
LET bc=USR 23306

REM Save a data block from its own address:
LET bc=USR 23309

REM Save a data block from address 'start', size 'length':
POKE 23549,INT(start/256):POKE 23548,start-256*PEEK23549
POKE 23547,INT(length/256):POKE 23546,length-256*PEEK23547
LET bc=USR 23309

REM On return from calls:
REM bc=0 - Ok
REM bc=1 - BREAK
REM bc=2 - Block not loaded

Best viewed with Any Browser Valid HTML 4.0! Authored by J.G.Harston
Last update: 19-Nov-2019