| Load routines

802F: Load the next code block

Continues from 5DF7 (to load the fast code block) and 8116 (to load the standard speed code block).
802F | LD SP,$80FC | Put the stack somewhere safe
8032 | LD IX,$81AB | The fast code block loads backwards from address 81AB; after the fast code block has loaded, this instruction is changed to 'LD IX,$4000' for the standard speed code block
8036 | LD DE,$C000 | Set DE (the byte counter) to a high enough value that it won't reach 0 before (a) 241 bytes have been loaded from the fast code block, or (b) the first 16572 bytes (4000-80BB) have been loaded from the standard speed code block
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; after the fast code block has loaded, this instruction is changed to 'LD B,$B0' for the standard speed code block
8089 | JR $80A5 | Jump forward to load the flag byte
This is the byte-loading loop. The first byte loaded is the flag byte.
808B | NOP |
808C | NOP |
808D | EX AF,AF' | Restore the flags
808E | JR NZ,$8095 | Jump if the first byte (the flag byte) has just been collected
8090 | LD (IX+$00),L | Load the byte read from tape into memory
8093 | JR $809F |
8095 | RL C | Save the carry flag in bit 0 of C temporarily
8097 | XOR L | L=first byte of the data block (the flag byte)
8098 | RET NZ | Reset the Spectrum if it wasn't 0xFF
8099 | LD A,C | Restore the carry flag
809A | RRA
809B | LD C,A | Restore C
809C | INC DE | Compensate for the 'DEC DE' below
809D | JR $80A1 | Jump forward to start loading bytes into memory
809F | DEC IX | IX=next address to load the byte from tape into; after the fast code block has loaded, this instruction is changed to 'INC IX' for the standard speed code block
80A1 | DEC DE | Decrease the byte counter
80A2 | EX AF,AF' | Save the flags (the zero flag is now set)
80A3 | LD B,$E3 | Set the timing constant; after the fast code block has loaded, this instruction is changed to 'LD B,$B2' for the standard speed code block
80A5 | LD L,$01 | Get ready to load eight bits from the tape
80A7 | CALL $8000 | Load one bit from the tape
80AA | RET NC | Reset the Spectrum if there was a loading error
80AB | LD A,$ED | Set the carry flag if a '1' was read from the tape, or reset it if a '0' was read; after the fast code block has loaded, the 'LD A,$ED' instruction is changed to 'LD A,$CB' for the standard speed code block
80AD | CP B
80AE | RL L | Move the bit into the L register
80B0 | LD B,$E1 | Set the timing constant for the next bit; after the fast code block has loaded, this instruction is changed to 'LD B,$B0' for the standard speed code block
80B2 | JP NC,$80A7 | Jump unless eight bits have been loaded
A full byte has just been read from the tape.
80B5 | LD A,H | Update the (ultimately unused) parity byte against the byte just read from the tape
80B6 | XOR L
80B7 | LD H,A
80B8 | LD A,D | Set the zero flag if the the byte counter has reached 0 (which never happens)
80B9 | OR E
80BA | JR NZ,$808B | Jump back to load another byte from the tape
When the bytes from 81AB downwards to 80BB have loaded from the fast code block, the instruction at 80BA above becomes:
80BA | JR NZ,$80BC |
And the code continues at 80BC. When the bytes from 4000 to 80BB have loaded from the standard speed code block, the instruction at 80BA becomes:
80BA | JR NZ,$807A |
At this stage, 807A reads as follows:
807A | LD (IX+$14),L | Load the byte read from tape into memory
807D | EXX |
807E | ADD IX,BC | Add 247 to IX
8080 | EXX |
8081 | JR NC,$8085 | Jump unless IX was incremented beyond FFFF
8083 | LD IXh,$7F | Reset IX to the appropriate range
8086 | JR $80A3 | Jump forward to load the next byte from tape
Now 32890 more bytes are loaded, the first at 81C7 and the last at 8086 (even though there is one more byte, 817D, left on the tape: see the save routine). Then 8086 reads as follows:
8086 | LD SP,$5D1B | Point the stack pointer at the game start address that was placed at 5D1B by the save routine
8089 | LD D,H |
808A | RET | To ($5D1B)=81C8