Save routine |
Up: Map |
The fast code block consists of two sections of data. The first section contains the 16573 bytes of data for addresses 4000-80BC. The second section contains 65535 bytes of data starting at address 80CB, moving forward in steps of 23 bytes, and ending at 809D.
Note that the last three bytes in the first section (addresses 80BA-80BC) are actually loaded into addresses 8086, 809D and 80B4 by the load routine. Note also that the last byte in the second section, for address 809D, is not loaded by the load routine.
|
||||||
80F5 | LD HL,$81B4 | 81B4 is where the game starts after loading | ||||
80F8 | LD ($5D19),HL | Store this address where it will be popped off the stack by the load routine | ||||
80FB | EXX | Prepare BC' for saving the second section of data | ||||
80FC | LD BC,$0017 | |||||
80FF | EXX | |||||
8100 | LD IX,$4000 | 4000 to 80BC will be saved first | ||||
8104 | LD DE,$40BC | |||||
8107 | LD A,$FF | A flag byte of 0xFF (the first byte saved) indicates a data block | ||||
8109 | LD HL,$0C98 | This constant will give a leader tone of about 2 seconds | ||||
810C | EX AF,AF' | |||||
810D | INC DE | Adjust the length and start address to allow for the flag byte | ||||
810E | DEC IX | |||||
8110 | DI | Disable interrupts | ||||
8111 | LD A,$02 | MIC on, border red | ||||
8113 | LD B,A | |||||
First create the 2-second leader tone.
|
||||||
8114 | DJNZ $8114 | |||||
8116 | OUT ($FE),A | |||||
8118 | XOR $0F | |||||
811A | LD B,$A4 | |||||
811C | DEC L | |||||
811D | JR NZ,$8114 | |||||
811F | DEC B | |||||
8120 | DEC H | |||||
8121 | JP P,$8114 | |||||
Then create the sync pulse.
|
||||||
8124 | LD B,$2F | |||||
8126 | DJNZ $8126 | |||||
8128 | OUT ($FE),A | |||||
812A | LD A,$0D | |||||
812C | LD B,$37 | |||||
812E | DJNZ $812E | |||||
8130 | OUT ($FE),A | |||||
It's time to save the first byte, which will be the flag byte (0xFF).
|
||||||
8132 | LD BC,$1A0E | B=0x1A (timing constant), C=0x0E (MIC off, border yellow) | ||||
8135 | EX AF,AF' | A=0xFF | ||||
8136 | LD L,A | L=0xFF | ||||
8137 | JP $8143 | Jump forward to save the flag byte | ||||
This is the main byte-saving loop.
|
||||||
813A | LD A,D | In the analagous ROM routine, the second instruction here is 'OR E', to check whether it's time to save the last byte (the parity byte) | ||||
813B | LD A,D | |||||
813C | JR Z,$814A | This jump (to save the parity byte) is never made | ||||
813E | LD L,(IX+$00) | Fetch the next byte to be saved | ||||
8141 | LD A,H | A=current parity byte | ||||
8142 | XOR L | Update this for the next byte to be saved | ||||
8143 | LD H,A | H=new parity byte | ||||
8144 | LD A,$01 | A=0x01 (MIC on, border blue) | ||||
8146 | SCF | Set the carry flag (which will act as the marker bit) | ||||
8147 | JP $8161 | Jump forward to save the byte | ||||
This section of code, if it were used, would save the parity byte.
|
||||||
814A | LD L,H | Pick up the parity byte in L | ||||
814B | JR $8141 | Save it | ||||
This is the bit-saving loop for the first section of data (4000-80BC).
|
||||||
814D | LD A,C | A=0x0E (MIC off, border yellow) for the second pass | ||||
814E | BIT 7,B | Set the zero flag to indicate that this is the second pass through the loop | ||||
8150 | DJNZ $8150 | |||||
8152 | JR NC,$8158 | Jump if we are saving a '0' | ||||
8154 | LD B,$20 | |||||
8156 | DJNZ $8156 | |||||
8158 | OUT ($FE),A | |||||
815A | LD B,$1D | Set the timing constant for the second pass | ||||
815C | JR NZ,$814D | Jump back for the second pass if we've just done the first | ||||
815E | DEC B | |||||
815F | XOR A | Clear the carry flag | ||||
8160 | INC A | A=0x01 (MIC on, border blue) | ||||
8161 | RL L | Move the bit to be saved into the carry flag, and the marker bit leftwards | ||||
8163 | JP NZ,$8150 | Jump unless we've saved all 8 bits of the byte | ||||
A byte from the first section (4000-80BC) has just been saved. Are there any more left?
|
||||||
8166 | DEC DE | Decrease the length counter | ||||
8167 | INC IX | Move to the next byte to be saved | ||||
8169 | LD B,$10 | Set the timing constant for the first bit of the next byte | ||||
816B | LD A,$7F | Return if the BREAK key is being pressed | ||||
816D | IN A,($FE) | |||||
816F | RRA | |||||
8170 | RET NC | |||||
8171 | LD A,D | Have we saved 4000 to 80BC yet? | ||||
8172 | INC A | |||||
8173 | JP NZ,$813A | Jump back if not | ||||
Now a further 65535 bytes are saved: starting at 80CB, moving forward in steps of 23 bytes, and ending at 809D.
|
||||||
8176 | LD A,D | IX=80BD and DE=FFFF the first time we get here | ||||
8177 | OR E | |||||
8178 | JR Z,$8186 | Jump if we have now saved 80CB onwards | ||||
817A | LD L,(IX+$0E) | IX+0x0E=80CB the first time we get here | ||||
817D | LD A,H | A=current parity byte | ||||
817E | XOR L | Update this for the next byte to be saved | ||||
817F | LD H,A | H=new parity byte | ||||
8180 | LD A,$01 | A=0x01 (MIC on, border blue) | ||||
8182 | SCF | Set the carry flag (which will act as the marker bit) | ||||
8183 | JP $819D | Jump forward to save the byte | ||||
This is where we come when all 82108 bytes have been saved.
|
||||||
8186 | LD L,$00 | |||||
8188 | RET | |||||
This is the bit-saving loop for the second section of data.
|
||||||
8189 | LD A,C | A=0x0E (MIC off, border yellow) for the second pass | ||||
818A | BIT 7,B | Set the zero flag to indicate that this is the second pass through the loop | ||||
818C | DJNZ $818C | |||||
818E | JR NC,$8194 | Jump if we are saving a '0' | ||||
8190 | LD B,$20 | |||||
8192 | DJNZ $8192 | |||||
8194 | OUT ($FE),A | |||||
8196 | LD B,$1D | Set the timing constant for the second pass | ||||
8198 | JR NZ,$8189 | Jump back for the second pass if we've just done the first | ||||
819A | DEC B | |||||
819B | XOR A | Clear the carry flag | ||||
819C | INC A | A=0x01 (MIC on, border blue) | ||||
819D | RL L | Move the bit to be saved into the carry flag, and the marker bit leftwards | ||||
819F | JP NZ,$818C | Jump unless we've saved all 8 bits of the byte | ||||
A byte from the second section has just been saved. Are there any more left?
|
||||||
81A2 | DEC DE | Decrease the length counter | ||||
81A3 | EXX | Move forward 23 bytes to the next byte to be saved | ||||
81A4 | ADD IX,BC | |||||
81A6 | EXX | |||||
81A7 | LD B,$10 | Set the timing constant for the first bit of the next byte | ||||
81A9 | LD A,$7F | These instructions check the BREAK key but do not act on the result | ||||
81AB | IN A,($FE) | |||||
81AD | RRA | |||||
81AE | JP $8176 | Save the next byte | ||||
The last 5 bytes of the first section saved make important changes to the load routine when the game is being loaded:
|
||||||
80B8 | JR NZ,$807D | This will replace the 'JR NZ,$808B' at 80B8, and kick off the loading of 65537 bytes from 8086 onwards (in steps of 23, all the way round to 8086 again) | ||||
80BA | DEFB $20 | This byte will replace the 0x31 at 8086, changing the instruction there from 'LD SP,$5D19' to 'JR NZ,$80A1' | ||||
80BB | DEFB $DD | This byte will be loaded into 809D (which already contains 0xDD) | ||||
80BC | DEFB $AD | This byte will be loaded into 80B4 (which already contains 0xAD) |
Up: Map |