| Load routines

802F: Fast load the main code block

Continues from 5D17.
802F | LD SP,$80FC | Put the stack somewhere safe
8032 | LD IX,$4000 | The fast code block starts loading at address 4000 (the start of the display file)
8036 | LD DE,$C000 | Set DE (the byte counter) to a high enough value that it won't reach 0 before the first 16570 bytes (4000-80B9) have been loaded
8039 | LD A,$FF | We expect the first byte loaded (the flag byte) to be 0xFF
803B | SCF | In the analogous ROM routine, setting the carry flag would indicate that we want to LOAD rather than VERIFY; here, this flag is not used
803C | INC D | Reset the zero flag, indicating that we haven't loaded the first byte of the data block (the flag byte) yet
803D | EX AF,AF' | Save these flags
803E | DEC D | Restore the value of DE
803F | DI | Disable interrupts
8040 | LD A,$0F | BORDER 7
8042 | OUT ($FE),A
8044 | IN A,($FE) | Collect an initial EAR port reading into bit 6 of A
8046 | RRA | Move it to bit 5 of A
8047 | AND $20 | Clear the extraneous bits (0-4 and 6-7)
8049 | OR $02 | The border will turn red when the first edge is found
804B | LD C,A | C will hold the border colour
804C | CP A | Set the zero flag to avoid returning at the next instruction
804D | RET NZ | In the analogous ROM routine, this instruction would return if the BREAK key is being pressed; here, the zero flag is always set
804E | CALL $800F | Listen for an edge
8051 | JR NC,$804D | Jump back to listen again if no edge was found within the time limit
An edge was found. Wait a bit and then listen again.
8053 | LD HL,$0415 | Wait for about one second
8056 | DJNZ $8056
8058 | DEC HL
8059 | LD A,H
805A | OR L
805B | JR NZ,$8056
805D | CALL $8000 | Are the edges still coming?
8060 | JR NC,$804D | Jump back if not
Check whether the signal is a leader tone.
8062 | LD B,$9C | 256 double edges arriving within a specific time limit constitute a valid leader tone
8064 | CALL $8000
8067 | JR NC,$804D
8069 | LD A,$C6
806B | CP B
806C | JR NC,$804E
806E | INC H
806F | JR NZ,$8062
This looks like a leader tone. Now listen for the first edge of the data block.
8071 | LD B,$C9 | Is the leader tone still there?
8073 | CALL $800F
8076 | JR NC,$804D | Jump back if not
8078 | LD A,B | Have we found the first edge of the data block?
8079 | CP $D4
807B | JR NC,$8071 | Jump back if not
The first edge of the data block has been detected.
807D | CALL $800F | Look for the second edge of the data block
8080 | RET NC | Reset the Spectrum if it can't be found
Prepare to load the data block.
8081 | LD A,C | The border will alternate between blue and yellow for the data block
8082 | XOR $03
8084 | LD C,A
8085 | LD H,$00 | Initialise the parity byte to 0
8087 | LD B,$E1 | Set the timing constant for the flag byte
8089 | JR $80A3 | Jump forward to load the flag byte
This is the byte-loading loop. The first byte loaded is the flag byte.
808B | EX AF,AF' | Restore the flags
808C | JR NZ,$8093 | Jump if the first byte (the flag byte) has just been collected
808E | LD (IX+$00),L | Load the byte read from tape into memory
8091 | JR $809D |
8093 | RL C | Save the carry flag in bit 0 of C temporarily
8095 | XOR L | L=first byte of the data block (the flag byte)
8096 | RET NZ | Reset the Spectrum if it wasn't 0xFF
8097 | LD A,C | Restore the carry flag
8098 | RRA
8099 | LD C,A | Restore C
809A | INC DE | Compensate for the 'DEC DE' below
809B | JR $809F | Jump forward to start loading bytes into memory
809D | INC IX | IX=next address to load the byte from tape into
809F | DEC DE | Decrease the byte counter
80A0 | EX AF,AF' | Save the flags (the zero flag is now set)
This inner loop loads the eight bits of a byte one-by-one from the tape into the L register.
80A1 | LD B,$E3 | Set the timing constant
80A3 | LD L,$01 | Get ready to load eight bits from the tape
80A5 | CALL $8000 | Load one bit from the tape
80A8 | RET NC | Reset the Spectrum if there was a loading error
80A9 | LD A,$ED | Set the carry flag if a '1' was read from the tape, or reset it if a '0' was read
80AB | CP B
80AC | RL L | Move the bit into the L register
80AE | LD B,$E1 | Set the timing constant for the next bit
80B0 | JP NC,$80A5 | Jump unless eight bits have been loaded
A full byte has just been read from the tape.
80B3 | LD A,H | Update the (ultimately unused) parity byte against the byte just read from the tape
80B4 | XOR L
80B5 | LD H,A
80B6 | LD A,D | Set the zero flag if the the byte counter has reached 0 (which never happens)
80B7 | OR E
80B8 | JR NZ,$808B | Jump back to load another byte from the tape
80BA | RET | (We never get here)
When the computer has loaded up to 80B9, the instruction at 80B8 is changed thus:
80B8 | JR NZ,$807D |
At this stage, 807D reads as follows:
807D | LD (IX-$34),L | Effectively LD ($8086),$20
8080 | EXX |
8081 | ADD IX,BC | Add 23 to IX
8083 | EXX |
8084 | SET 7,L |
The instruction at 807D above changes the instruction at 8086 from 'LD SP,$5D19' to:
8086 | JR NZ,$80A1 | Jump forward to load the next byte from the tape
Now 65536 more bytes are loaded, the last of which is at 8086 (even though there is one more byte, 809D, left on the tape: see the save routine). Then 8086 reads as follows:
8086 | LD SP,$5D19 | Point the stack pointer at the game start address that was placed at 5D19 by the routine at 7EE4
8089 | LD D,H |
808A | RET | To ($5D19)=5EE0