|Prev: 053F||Up: Map||Next: 05E3|
This subroutine is called to load the header information and later load or verify an actual block of data from a tape.
|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.|
|055E||LD HL,$053F||Preload the machine stack with the address SA_LD_RET.|
|0562||IN A,($FE)||Make an initial read of port '254'.|
|0564||RRA||Rotate the byte obtained but keep only the EAR bit.|
|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.|
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.|
|057B||CALL LD_EDGE_2||Continue only if two edges are found within the allowed time period.|
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.|
|0587||LD A,$C6||However the edges must have been found within about 3,000 T states of each other.|
|058C||INC H||Count the pair of edges in the H register until '256' pairs have been found.|
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.|
|059B||CALL LD_EDGE_1||The finishing edge of the 'on' pulse must exist. (Return carry flag reset.)|
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.|
|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.)|
|05B7||LD A,C||Restore the carry flag now.|
|05BA||INC DE||Increase the counter to compensate for its 'decrease' after the jump.|
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'.|
|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.|
|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.|
|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.)|
|Prev: 053F||Up: Map||Next: 05E3|