Jet Set Willy: Routine at 873C

| Routines

873C: Read the keyboard during code entry

Used by the routine at 86C3. Waits for '1', '2', '3', '4' or ENTER to be pressed and either prints a coloured block or validates the entered code. Returns to the routine at 869F if ENTER is being pressed, with the zero flag reset if the entered code is correct.
Input
IX | Attribute file address of the flashing 2x2 block
873C | LD BC,$F7FE | Read keys 1-2-3-4-5
873F | IN A,(C)
8741 | AND $0F | Is '1', '2', '3' or '4' (still) being pressed?
8743 | CP $0F
8745 | JR NZ,$873C | Jump back if so
8747 | LD B,$BF | Read keys H-J-K-L-ENTER
8749 | IN A,(C)
874B | BIT 0,A | Is ENTER being pressed?
874D | JR NZ,$8785 | Jump if not
874F | LD A,($5959) | Pick up the attribute byte of the fourth 2x2 block at (10,25)
8752 | AND $7F | Has the fourth digit been entered yet?
8754 | CP $07
8756 | JR Z,$8785 | Jump if not
We have four coloured blocks, and ENTER is being pressed. Time to validate the entered code.
8758 | SUB $08 | Compute bits 0 and 1 of the entered code from the attribute byte of the fourth coloured block at (10,25) and store them in C
875A | AND $18
875C | RRCA
875D | RRCA
875E | RRCA
875F | LD C,A
8760 | LD A,($5953) | Compute bits 4 and 5 of the entered code from the attribute byte of the second coloured block at (10,19) and store them in C (alongside bits 0 and 1)
8763 | SUB $08
8765 | AND $18
8767 | RLCA
8768 | OR C
8769 | LD C,A
876A | LD A,($5956) | Compute bits 2 and 3 of the entered code from the attribute byte of the third coloured block at (10,22) and store them in C (alongside bits 0, 1, 4 and 5)
876D | SUB $08
876F | AND $18
8771 | RRCA
8772 | OR C
8773 | LD C,A
8774 | LD A,($5950) | Compute bits 6 and 7 of the entered code from the attribute byte of the first coloured block at (10,16) in A
8777 | SUB $08
8779 | AND $18
877B | RLCA
877C | RLCA
877D | RLCA
877E | POP HL | Drop the return address from the stack
877F | OR C | Merge bits 0-5 of the entered code into A; now A holds all 8 bits of the entered code
8780 | LD HL,$85E4 | Point HL at 85E4 (where the correct entry code is stored)
8783 | CP (HL) | Set the zero flag if the entered code matches
8784 | RET | Return to the routine at 869F
Here we check whether '1', '2', '3' or '4' is being pressed.
8785 | SET 7,(IX+$00) | Make sure the current 2x2 block is flashing
8789 | SET 7,(IX+$01)
878D | SET 7,(IX+$20)
8791 | SET 7,(IX+$21)
8795 | LD BC,$F7FE | Read keys 1-2-3-4-5
8798 | IN A,(C)
879A | AND $0F | Keep only bits 0-3 (keys 1-2-3-4)
879C | LD E,$08 | E=0x08 (INK 0: PAPER 1)
879E | CP $0E | Is '1' alone being pressed?
87A0 | JR Z,$87B5 | Jump if so
87A2 | LD E,$10 | E=0x10 (INK 0: PAPER 2)
87A4 | CP $0D | Is '2' alone being pressed?
87A6 | JR Z,$87B5 | Jump if so
87A8 | LD E,$18 | E=0x18 (INK 0: PAPER 3)
87AA | CP $0B | Is '3' alone being pressed?
87AC | JR Z,$87B5 | Jump if so
87AE | LD E,$20 | E=0x20 (INK 0: PAPER 4)
87B0 | CP $07 | Is '4' alone being pressed?
87B2 | JP NZ,$8747 | If not, jump back to check the ENTER key
Exactly one of the number keys '1', '2', '3' or '4' is being pressed. E holds the corresponding attribute byte to use for the coloured block.
87B5 | LD (IX+$00),E | Set the colour of the 2x2 block (no longer flashing)
87B8 | LD (IX+$01),E
87BB | LD (IX+$20),E
87BE | LD (IX+$21),E
87C1 | LD BC,$0018 | Pause for about 0.02s
87C4 | DJNZ $87C4
87C6 | DEC C
87C7 | JR NZ,$87C4
87C9 | RET |