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