Spectrum ROM | Routines |
Prev: 01343 | Up: Map |
This subroutine is called to load the header information and later load or verify an actual block of data from a tape.
|
|||||||
LD_BYTES | 01366 | INC D | This resets the zero flag. (D cannot hold +FF.) | ||||
01367 | 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. | |||||
01368 | DEC D | Restore D to its original value. | |||||
01369 | DI | The maskable interrupt is now disabled. | |||||
01370 | LD A,15 | The border is made white. | |||||
01372 | OUT (254),A | ||||||
01374 | LD HL,1343 | Preload the machine stack with the address SA_LD_RET. | |||||
01377 | PUSH HL | ||||||
01378 | IN A,(254) | Make an initial read of port '254'. | |||||
01380 | RRA | Rotate the byte obtained but keep only the EAR bit. | |||||
01381 | AND 32 | ||||||
01383 | OR 2 | Signal red border. | |||||
01385 | LD C,A | Store the value in the C register (+22 for 'off' and +02 for 'on' - the present EAR state). | |||||
01386 | 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 | 01387 | RET NZ | Return if the BREAK key is being pressed. | ||||
LD_START | 01388 | 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. | ||||
01391 | JR NC,LD_BREAK | ||||||
The next stage involves waiting a while and then showing that the signal is still pulsing.
|
|||||||
01393 | LD HL,1045 | The length of this waiting period will be almost one second in duration. | |||||
LD_WAIT | 01396 | DJNZ LD_WAIT | |||||
01398 | DEC HL | ||||||
01399 | LD A,H | ||||||
01400 | OR L | ||||||
01401 | JR NZ,LD_WAIT | ||||||
01403 | CALL LD_EDGE_2 | Continue only if two edges are found within the allowed time period. | |||||
01406 | JR NC,LD_BREAK | ||||||
Now accept only a 'leader signal'.
|
|||||||
LD_LEADER | 01408 | LD B,156 | The timing constant. | ||||
01410 | CALL LD_EDGE_2 | Continue only if two edges are found within the allowed time period. | |||||
01413 | JR NC,LD_BREAK | ||||||
01415 | LD A,198 | However the edges must have been found within about 3,000 T states of each other. | |||||
01417 | CP B | ||||||
01418 | JR NC,LD_START | ||||||
01420 | INC H | Count the pair of edges in the H register until '256' pairs have been found. | |||||
01421 | JR NZ,LD_LEADER | ||||||
After the leader come the 'off' and 'on' parts of the sync pulse.
|
|||||||
LD_SYNC | 01423 | LD B,201 | The timing constant. | ||||
01425 | 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. | |||||
01428 | JR NC,LD_BREAK | ||||||
01430 | LD A,B | ||||||
01431 | CP 212 | ||||||
01433 | JR NC,LD_SYNC | ||||||
01435 | CALL LD_EDGE_1 | The finishing edge of the 'on' pulse must exist. (Return carry flag reset.) | |||||
01438 | 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.
|
|||||||
01439 | LD A,C | The border colours from now on will be blue and yellow. | |||||
01440 | XOR 3 | ||||||
01442 | LD C,A | ||||||
01443 | LD H,0 | Initialise the 'parity matching' byte to zero. | |||||
01445 | LD B,176 | Set the timing constant for the flag byte. | |||||
01447 | 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 | 01449 | EX AF,AF' | Fetch the flags. | ||||
01450 | JR NZ,LD_FLAG | Jump forward only when handling the first byte. | |||||
01452 | JR NC,LD_VERIFY | Jump forward if verifying a tape. | |||||
01454 | LD (IX+0),L | Make the actual load when required. | |||||
01457 | JR LD_NEXT | Jump forward to load the next byte. | |||||
LD_FLAG | 01459 | RL C | Keep the carry flag in a safe place temporarily. | ||||
01461 | XOR L | Return now if the type flag does not match the first byte on the tape. (Carry flag reset.) | |||||
01462 | RET NZ | ||||||
01463 | LD A,C | Restore the carry flag now. | |||||
01464 | RRA | ||||||
01465 | LD C,A | ||||||
01466 | INC DE | Increase the counter to compensate for its 'decrease' after the jump. | |||||
01467 | JR LD_DEC | ||||||
If a data block is being verified then the freshly loaded byte is tested against the original byte.
|
|||||||
LD_VERIFY | 01469 | LD A,(IX+0) | Fetch the original byte. | ||||
01472 | XOR L | Match it against the new byte. | |||||
01473 | RET NZ | Return if 'no match'. (Carry flag reset.) | |||||
A new byte can now be collected from the tape.
|
|||||||
LD_NEXT | 01474 | INC IX | Increase the 'destination'. | ||||
LD_DEC | 01476 | DEC DE | Decrease the 'counter'. | ||||
01477 | EX AF,AF' | Save the flags. | |||||
01478 | LD B,178 | Set the timing constant. | |||||
LD_MARKER | 01480 | LD L,1 | 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 | 01482 | CALL LD_EDGE_2 | Find the length of the 'off' and 'on' pulses of the next bit. | ||||
01485 | RET NC | Return if the time period is exceeded. (Carry flag reset.) | |||||
01486 | LD A,203 | Compare the length against approx. 2,400 T states, resetting the carry flag for a '0' and setting it for a '1'. | |||||
01488 | CP B | ||||||
01489 | RL L | Include the new bit in the L register. | |||||
01491 | LD B,176 | Set the timing constant for the next bit. | |||||
01493 | 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.
|
|||||||
01496 | LD A,H | Fetch the 'parity matching' byte and include the new byte. | |||||
01497 | XOR L | ||||||
01498 | 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.
|
|||||||
01499 | LD A,D | Make a further pass if the DE register pair does not hold zero. | |||||
01500 | OR E | ||||||
01501 | JR NZ,LD_LOOP | ||||||
01503 | LD A,H | Fetch the 'parity matching' byte. | |||||
01504 | CP 1 | Return with the carry flag set if the value is zero. (Carry flag reset if in error.) | |||||
01506 | RET |
Prev: 01343 | Up: Map |