Prev: 053F Up: Map Next: 05E3
0556: THE 'LD-BYTES' SUBROUTINE
Used by the routines at SAVE_ETC and LD_BLOCK.
This subroutine is called to load the header information and later load or verify an actual block of data from a tape.
Input
A +00 (header block) or +FF (data block)
F Carry flag set if loading, reset if verifying
DE Block length
IX Start address
Output
F Carry flag reset if there was an error
LD_BYTES 0556 INC D This resets the zero flag. (D cannot hold +FF.)
0557 EX AF,AF' The A register holds +00 for a header and +FF for a block of data. The carry flag is reset for verifying and set for loading.
0558 DEC D Restore D to its original value.
0559 DI The maskable interrupt is now disabled.
055A LD A,$0F The border is made white.
055C OUT ($FE),A
055E LD HL,$053F Preload the machine stack with the address SA_LD_RET.
0561 PUSH HL
0562 IN A,($FE) Make an initial read of port '254'.
0564 RRA Rotate the byte obtained but keep only the EAR bit.
0565 AND $20
0567 OR $02 Signal red border.
0569 LD C,A Store the value in the C register (+22 for 'off' and +02 for 'on' - the present EAR state).
056A CP A Set the zero flag.
The first stage of reading a tape involves showing that a pulsing signal actually exists (i.e. 'on/off' or 'off/on' edges).
LD_BREAK 056B RET NZ Return if the BREAK key is being pressed.
LD_START 056C CALL LD_EDGE_1 Return with the carry flag reset if there is no 'edge' within approx. 14,000 T states. But if an 'edge' is found the border will go cyan.
056F JR NC,LD_BREAK
The next stage involves waiting a while and then showing that the signal is still pulsing.
0571 LD HL,$0415 The length of this waiting period will be almost one second in duration.
LD_WAIT 0574 DJNZ LD_WAIT
0576 DEC HL
0577 LD A,H
0578 OR L
0579 JR NZ,LD_WAIT
057B CALL LD_EDGE_2 Continue only if two edges are found within the allowed time period.
057E JR NC,LD_BREAK
Now accept only a 'leader signal'.
LD_LEADER 0580 LD B,$9C The timing constant.
0582 CALL LD_EDGE_2 Continue only if two edges are found within the allowed time period.
0585 JR NC,LD_BREAK
0587 LD A,$C6 However the edges must have been found within about 3,000 T states of each other.
0589 CP B
058A JR NC,LD_START
058C INC H Count the pair of edges in the H register until '256' pairs have been found.
058D JR NZ,LD_LEADER
After the leader come the 'off' and 'on' parts of the sync pulse.
LD_SYNC 058F LD B,$C9 The timing constant.
0591 CALL LD_EDGE_1 Every edge is considered until two edges are found close together - these will be the start and finishing edges of the 'off' sync pulse.
0594 JR NC,LD_BREAK
0596 LD A,B
0597 CP $D4
0599 JR NC,LD_SYNC
059B CALL LD_EDGE_1 The finishing edge of the 'on' pulse must exist. (Return carry flag reset.)
059E RET NC
The bytes of the header or the program/data block can now be loaded or verified. But the first byte is the type flag.
059F LD A,C The border colours from now on will be blue and yellow.
05A0 XOR $03
05A2 LD C,A
05A3 LD H,$00 Initialise the 'parity matching' byte to zero.
05A5 LD B,$B0 Set the timing constant for the flag byte.
05A7 JR LD_MARKER Jump forward into the byte loading loop.
The byte loading loop is used to fetch the bytes one at a time. The flag byte is first. This is followed by the data bytes and the last byte is the 'parity' byte.
LD_LOOP 05A9 EX AF,AF' Fetch the flags.
05AA JR NZ,LD_FLAG Jump forward only when handling the first byte.
05AC JR NC,LD_VERIFY Jump forward if verifying a tape.
05AE LD (IX+$00),L Make the actual load when required.
05B1 JR LD_NEXT Jump forward to load the next byte.
LD_FLAG 05B3 RL C Keep the carry flag in a safe place temporarily.
05B5 XOR L Return now if the type flag does not match the first byte on the tape. (Carry flag reset.)
05B6 RET NZ
05B7 LD A,C Restore the carry flag now.
05B8 RRA
05B9 LD C,A
05BA INC DE Increase the counter to compensate for its 'decrease' after the jump.
05BB JR LD_DEC
If a data block is being verified then the freshly loaded byte is tested against the original byte.
LD_VERIFY 05BD LD A,(IX+$00) Fetch the original byte.
05C0 XOR L Match it against the new byte.
05C1 RET NZ Return if 'no match'. (Carry flag reset.)
A new byte can now be collected from the tape.
LD_NEXT 05C2 INC IX Increase the 'destination'.
LD_DEC 05C4 DEC DE Decrease the 'counter'.
05C5 EX AF,AF' Save the flags.
05C6 LD B,$B2 Set the timing constant.
LD_MARKER 05C8 LD L,$01 Clear the 'object' register apart from a 'marker' bit.
The following loop is used to build up a byte in the L register.
LD_8_BITS 05CA CALL LD_EDGE_2 Find the length of the 'off' and 'on' pulses of the next bit.
05CD RET NC Return if the time period is exceeded. (Carry flag reset.)
05CE LD A,$CB Compare the length against approx. 2,400 T states, resetting the carry flag for a '0' and setting it for a '1'.
05D0 CP B
05D1 RL L Include the new bit in the L register.
05D3 LD B,$B0 Set the timing constant for the next bit.
05D5 JP NC,LD_8_BITS Jump back whilst there are still bits to be fetched.
The 'parity matching' byte has to be updated with each new byte.
05D8 LD A,H Fetch the 'parity matching' byte and include the new byte.
05D9 XOR L
05DA LD H,A Save it once again.
Passes round the loop are made until the 'counter' reaches zero. At that point the 'parity matching' byte should be holding zero.
05DB LD A,D Make a further pass if the DE register pair does not hold zero.
05DC OR E
05DD JR NZ,LD_LOOP
05DF LD A,H Fetch the 'parity matching' byte.
05E0 CP $01 Return with the carry flag set if the value is zero. (Carry flag reset if in error.)
05E2 RET
Prev: 053F Up: Map Next: 05E3