Prev: 4000 Up: Map Next: 5BD7
5B00: The game has loaded
The game starts here.
start 5B00 DI Disable interrupts
5B01 LD SP,$5C00 Set stack pointer
Copy $4910 bytes from $5C00+ to $76F0+ (copying backwards to avoid overlap).
5B04 LD HL,$A50F Final source byte
5B07 LD DE,$BFFF Final destination byte
5B0A LD BC,$4910 Count
5B0D LDDR Copy
Detect 128K machines.
Assuming bank 0 is mapped in to start with, we copy a byte from bank 0.
5B0F LD HL,$FFF0 Read the byte at $FFF0 into E
5B12 LD E,(HL)
Now we modify it, then store it back after attempting to page in bank 1.
5B13 LD A,$01 Attempt to map RAM bank 1 to $C000
5B15 LD BC,$7FFD
5B18 OUT (C),A
5B1A LD A,E Increment the read byte by $FD (being a handy non-zero value)
5B1B ADD A,C
5B1C LD (HL),A Store it
If the modified byte remains present after restoring bank 0 then it's a 48K machine.
5B1D XOR A Attempt to map RAM bank 0 to $C000
5B1E OUT (C),A
5B20 LD A,(HL) Fetch potentially changed byte
5B21 LD (HL),E Restore original byte
5B22 LD HL,$5B7D Point HL at loader_commands_48K
If byte was modified no paging took place, so this is a 48K machine.
5B25 CP E If modified, jump to loader with loader_commands_48K setup
5B26 JR NZ,loader
mode_is_128k 5B28 LD HL,$5B87 Otherwise point HL at loader_commands_128K
Loader accepts a command list and uses it to load the game into memory. The 48K command list at loader_commands_48K loads stage 1, then starts the game. The 128K command list at loader_commands_128K loads stages while paging in the appropriate banks, then starts the game.
loader 5B2B LD E,(HL) Load a handler address from HL
5B2C INC HL
5B2D LD D,(HL)
5B2E INC HL
5B2F PUSH DE Call the handler
5B30 RET
Loader handler that loads a stage.
loader_load 5B31 PUSH HL Preserve command list address
5B32 LD IX,$5BD5 Address
5B36 LD DE,$0002 Count
5B39 CALL loader_load_chunk Call loader_load_chunk
5B3C POP HL Restore command list address
loader_load_headerless 5B3D LD E,(HL) Load address into IX
5B3E INC HL
5B3F LD D,(HL)
5B40 INC HL
5B41 PUSH DE
5B42 POP IX
5B44 LD E,(HL) Load count into DE
5B45 INC HL
5B46 LD D,(HL)
5B47 INC HL
5B48 PUSH HL Preserve command list address
5B49 CALL loader_load_chunk Call loader_load_chunk
5B4C POP HL Restore command list address
5B4D JR loader Process next entry
Subroutine that loads DE bytes to address IX.
loader_load_chunk 5B4F CALL tape_load Call tape_load
5B52 RET C Return if no errors
Infinitely cycle through border colours if a tape loading error occurred.
loader_load_failed 5B53 OUT ($FE),A
5B55 INC A
5B56 JR loader_load_failed
Loader handler that pages in the specified RAM bank.
loader_set_bank 5B58 LD A,$80 Page in RAM where interrupt vector lives
5B5A LD I,A Set Interrupt Control Vector Register
5B5C LD A,(HL) Load 128K paging flags byte
5B5D INC HL Second byte is unused
5B5E INC HL
5B5F LD BC,$7FFD 128K: Set paging register
5B62 OUT (C),A
5B64 JR loader Process next entry
Loader handler that copies data around.
loader_copy 5B66 PUSH HL Preserve command list address
5B67 LD HL,$5C00 Move $5C00..$76EF to $C000 onwards
5B6A LD DE,$C000
5B6D LD BC,$1AF0
5B70 LDIR
5B72 POP HL Restore command list address
5B73 JR loader Process next entry
Loader handler that starts the game.
loader_done 5B75 LD A,(HL) Load entrypoint address from HL
5B76 INC HL
5B77 LD H,(HL)
5B78 LD L,A
5B79 XOR A Set border to black
5B7A OUT ($FE),A
5B7C JP (HL) Exit via entrypoint just read
Loader commands for 48K mode.
loader_commands_48K 5B7D DEFW loader_load loader_load
5B7F DEFW bitmap_horizon,$1AF0 Stage 1: at $5C00 load $1AF0 bytes
5B83 DEFW loader_done loader_done
5B85 DEFW entrypt_48k entrypt_48k
Loader commands for 128K mode.
loader_commands_128K 5B87 DEFW loader_load loader_load
5B89 DEFW bitmap_horizon,$1AF0 Stage 1: at $5C00 load $1AF0 bytes
5B8D DEFW loader_set_bank loader_set_bank
5B8F DEFB $01,$00 Bank 1 (second byte is unused here)
5B91 DEFW loader_copy loader_copy
5B93 DEFW loader_load loader_load
5B95 DEFW $E000,$1AF0 Stage 2: at $E000 load $1AF0 bytes
5B99 DEFW loader_set_bank loader_set_bank
5B9B DEFB $06,$00 Bank 6
5B9D DEFW loader_load loader_load
5B9F DEFW $C000,$1AF0 Stage 3: at $C000 load $1AF0 bytes
5BA3 DEFW loader_load loader_load
5BA5 DEFW $E000,$1AF0 Stage 4: at $E000 load $1AF0 bytes
5BA9 DEFW loader_set_bank loader_set_bank
5BAB DEFB $07,$00 Bank 7
5BAD DEFW loader_load loader_load
5BAF DEFW $C000,$1AF0 Stage 5: at $C000 load $1AF0 bytes
5BB3 DEFW loader_load loader_load
5BB5 DEFW $E000,$1AF0 End screen: at $E000 load $1AF0 bytes
5BB9 DEFW loader_set_bank loader_set_bank
5BBB DEFB $03,$00 Bank 3
5BBD DEFW loader_load_headerless loader_load_headerless
5BBF DEFW $C000,$4000 Title screen: at $C000 load $4000 bytes
5BC3 DEFW loader_set_bank loader_set_bank
5BC5 DEFB $04,$00 Bank 4
5BC7 DEFW loader_load_headerless loader_load_headerless
5BC9 DEFW $C000,$4000 Sampled speech: at $C000 load $4000 bytes
5BCD DEFW loader_set_bank loader_set_bank
5BCF DEFB $00,$00 Bank 0
5BD1 DEFW loader_done loader_done
5BD3 DEFW entrypt_128k entrypt_128k
loader_scratch 5BD5 DEFB $01,$01 loader_load loads two bytes to here. -- unsure what uses them
Prev: 4000 Up: Map Next: 5BD7