![]() |
Load routines |
| Prev: 8000 | Up: Map | Next: 80BC |
| 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 | ||
| Prev: 8000 | Up: Map | Next: 80BC |