Jet Set Willy: Routine at 87CA

| Routines

87CA: Display the title screen and play the theme tune

Used by the routines at 869F, 89AD and 8C4A. The first thing this routine does is initialise some game status buffer variables in preparation for the next game.
87CA | XOR A | A=0
87CB | LD ($85CE),A | Initialise the Kempston joystick indicator at 85CE
87CE | LD ($85E1),A | Initialise the in-game music note index at 85E1
87D1 | LD ($85CD),A | Initialise the (unused) screen flash counter at 85CD
87D4 | LD ($85D1),A | Initialise the airborne status indicator at 85D1
87D7 | LD ($85CB),A | Initialise the minute counter at 85CB
87DA | LD ($85E0),A | Initialise the inactivity timer at 85E0
87DD | LD ($85DF),A | Initialise the game mode indicator at 85DF
87E0 | LD A,$07 | Initialise the number of lives remaining at 85CC
87E2 | LD ($85CC),A
87E5 | LD A,$D0 | Initialise Willy's y-coordinate at 85CF
87E7 | LD ($85CF),A
87EA | LD A,$21 | Initialise the current room number at 8420 to 0x21 (The Bathroom)
87EC | LD ($8420),A
87EF | LD HL,$5DB4 | Initialise Willy's coordinates at 85D3 to (13,20)
87F2 | LD ($85D3),HL
87F5 | LD HL,$857C | Initialise the number of items collected at 857C to "000"
87F8 | LD (HL),$30
87FA | INC HL
87FB | LD (HL),$30
87FD | INC HL
87FE | LD (HL),$30
8800 | LD H,$A4 | Page 0xA4 holds the first byte of each entry in the item table
8802 | LD A,($A3FF) | Pick up the index of the first item from A3FF
8805 | LD L,A | Point HL at the entry for the first item
8806 | LD ($85DE),A | Initialise the counter of items remaining at 85DE
8809 | SET 6,(HL) | Set the collection flag for every item in the item table at A400
880B | INC L
880C | JR NZ,$8809
880E | LD HL,$85E2 | Initialise the keypress flag in bit 0 at 85E2
8811 | SET 0,(HL)
Next, prepare the screen.
8813 | LD HL,$4000 | Clear the entire display file
8816 | LD DE,$4001
8819 | LD BC,$17FF
881C | LD (HL),$00
881E | LDIR
8820 | LD HL,$9800 | Copy the attribute bytes for the title screen from 9800 and 9A00 to the attribute file
8823 | LD BC,$0300
8826 | LDIR
8828 | LD HL,$5A60 | Copy the attribute value 0x46 (INK 6: PAPER 0: BRIGHT 1) into the row of 32 cells from (19,0) to (19,31) on the screen
882B | LD DE,$5A61
882E | LD BC,$001F
8831 | LD (HL),$46
8833 | LDIR
8835 | LD IX,$8454 | Print "+++++ Press ENTER to Start +++++" (see 8454) at (19,0)
8839 | LD DE,$5060
883C | LD C,$20
883E | CALL $9680
8841 | LD DE,$5800 | Point DE at the first byte of the attribute file
The following loop scans the top two-thirds of the attribute file, which contains values 0x00, 0x04, 0x05, 0x08, 0x09, 0x24, 0x25, 0x28, 0x29, 0x2C, 0x2D and 0xD3 (copied from 9800). Whenever a value other than 0x00, 0x09, 0x24, 0x2D or 0xD3 is found, a triangle UDG is drawn at the corresponding location in the display file.
8844 | LD A,(DE) | Pick up a byte from the attribute file
8845 | OR A | Is it 0x00 (INK 0: PAPER 0)?
8846 | JR Z,$888E | If so, jump to consider the next byte in the attribute file
8848 | CP $D3 | Is it 0xD3 (INK 3: PAPER 2: BRIGHT 1: FLASH 1)?
884A | JR Z,$888E | If so, jump to consider the next byte in the attribute file
884C | CP $09 | Is it 0x09 (INK 1: PAPER 1)?
884E | JR Z,$888E | If so, jump to consider the next byte in the attribute file
8850 | CP $2D | Is it 0x2D (INK 5: PAPER 5)?
8852 | JR Z,$888E | If so, jump to consider the next byte in the attribute file
8854 | CP $24 | Is it 0x24 (INK 4: PAPER 4)?
8856 | JR Z,$888E | If so, jump to consider the next byte in the attribute file
8858 | LD C,$00 | C=0; this will be used as an offset from the triangle UDG base address (8431)
885A | CP $08 | Is the attribute value 0x08 (INK 0: PAPER 1)?
885C | JR Z,$8871 | Jump if so
885E | CP $29 | Is it 0x29 (INK 1: PAPER 5)?
8860 | JR Z,$8871 | Jump if so
8862 | CP $2C | Is it 0x2C (INK 4: PAPER 5)?
8864 | JR Z,$886E | Jump if so
8866 | CP $05 | Is it 0x05 (INK 5: PAPER 0)?
8868 | JR Z,$8871 | Jump if so
886A | LD C,$10 | Set the triangle UDG offset to 0x10
886C | JR $8871 |
886E | LD A,$25 | Change the attribute byte here from 0x2C (INK 4: PAPER 5) to 0x25 (INK 5: PAPER 4)
8870 | LD (DE),A
8871 | LD A,E | Point HL at the triangle UDG to draw (8431, 8439, 8441 or 8449)
8872 | AND $01
8874 | RLCA
8875 | RLCA
8876 | RLCA
8877 | OR C
8878 | LD C,A
8879 | LD B,$00
887B | LD HL,$8431
887E | ADD HL,BC
887F | PUSH DE | Save the attribute file address briefly
8880 | BIT 0,D | Set the zero flag if we're still in the top third of the attribute file
8882 | LD D,$40 | Point DE at the top third of the display file
8884 | JR Z,$8888 | Jump if we're still in the top third of the attribute file
8886 | LD D,$48 | Point DE at the middle third of the display file
8888 | LD B,$08 | There are eight pixel rows in a triangle UDG
888A | CALL $969B | Draw a triangle UDG on the screen
888D | POP DE | Restore the attribute file address to DE
888E | INC DE | Point DE at the next byte in the attribute file
888F | LD A,D | Have we finished scanning the top two-thirds of the attribute file yet?
8890 | CP $5A
8892 | JP NZ,$8844 | If not, jump back to examine the next byte
Now check whether there is a joystick connected.
8895 | LD BC,$001F | This is the joystick port
8898 | DI | Disable interrupts (which are already disabled)
8899 | XOR A | A=0
889A | IN E,(C) | Combine 256 readings of the joystick port in A; if no joystick is connected, some of these readings will have bit 5 set
889C | OR E
889D | DJNZ $889A
889F | AND $20 | Is a joystick connected (bit 5 reset)?
88A1 | JR NZ,$88A8 | Jump if not
88A3 | LD A,$01 | Set the Kempston joystick indicator at 85CE to 1
88A5 | LD ($85CE),A
And finally, play the theme tune and check for keypresses. Your browser doesn't support HTML5 audio. Here is a link to the audio instead.
88A8 | LD HL,$85FB | Point HL at the theme tune data at 85FB
88AB | CALL $96A2 | Play the theme tune
88AE | JP NZ,$88FC | Start the game if ENTER, 0 or the fire button was pressed
No key was pressed while the theme tune was playing, so scroll a message across the screen while repeatedly producing a screeching sound effect. Your browser doesn't support HTML5 audio. Here is a link to the audio instead.
88B1 | XOR A | Initialise the temporary game status buffer variable at 85E4 to 0; this will be used as an index for the message scrolled across the screen (see 8454)
88B2 | LD ($85E4),A
88B5 | CALL $8AEB | Cycle the INK and PAPER colours
88B8 | LD HL,$5A60 | Copy the attribute value 0x4F (INK 7: PAPER 1: BRIGHT 1) into the row of 32 cells from (19,0) to (19,31) on the screen
88BB | LD DE,$5A61
88BE | LD BC,$001F
88C1 | LD (HL),$4F
88C3 | LDIR
88C5 | LD A,($85E4) | Pick up the message index from 85E4
88C8 | LD IX,$8454 | Point IX at the corresponding location in the message at 8454
88CC | LD E,A
88CD | LD D,$00
88CF | ADD IX,DE
88D1 | LD DE,$5060 | Print 32 characters of the message at (19,0)
88D4 | LD C,$20
88D6 | CALL $9680
88D9 | LD A,($85E4) | Prepare a value between 0x32 and 0x51 in A (for the routine at 96DE)
88DC | AND $1F
88DE | ADD A,$32
88E0 | CALL $96DE | Make a sound effect
88E3 | LD BC,$AFFE | Read keys H-J-K-L-ENTER and 6-7-8-9-0
88E6 | IN A,(C)
88E8 | AND $01 | Keep only bit 0 of the result (ENTER, 0)
88EA | CP $01 | Was ENTER or 0 pressed?
88EC | JR NZ,$88FC | Jump if so to start the game
88EE | LD A,($85E4) | Pick up the message index from 85E4
88F1 | INC A | Increment it
88F2 | CP $E0 | Set the zero flag if we've reached the end of the message
88F4 | LD ($85E4),A | Store the new message index at 85E4
88F7 | JR NZ,$88B5 | Jump back unless we've finished scrolling the message across the screen
88F9 | JP $8813 | Jump back to prepare the screen and play the theme tune again