Prev: 7B74 Up: Map Next: 7BEE
7B86: Read a key
Scans the keyboard directly through port $FE (the game does not use the ROM keyboard routine or interrupts) and returns the ASCII code of a key that has just been pressed, or 0 if no new key has been pressed. Holding a key down does not repeat it.
The routine first waits a few milliseconds (7B6B), then reads each of the eight half-rows in turn, starting with port $FEFE (CAPS SHIFT to V) and rotating the high byte of the port address to reach the next row. Each reading is ORed with that row's mask from 7B74. A key counts as newly pressed if its bit is 0 now but was 1 in the previous reading kept at 7B7E; the row and bits of such a key are saved at 7B7C.
If a new key was found, its row and bit are turned into a number from 0 to 39 (row x 5 + bit, 7BC0-7BCE). Then the shift keys are checked directly: if CAPS SHIFT is held, or SYMBOL SHIFT is not, the normal table at 7BEE is used; if SYMBOL SHIFT is held (and CAPS SHIFT is not), the symbol table at 7C16 is used. The table entry is returned in A.
In my emulator I replaced this routine with one that fed typed commands to the game.
Output
A ASCII code of the key, or 0
7B86 PUSH HL Save HL
7B87 PUSH IX Save IX
7B89 PUSH BC Save BC
7B8A CALL $7B6B Short delay; clear the new-key record
7B8D LD ($7B7C),BC Store BC in the new key record
7B91 LD HL,$7B7E HL = 7B7E
7B94 LD IX,$7B74 IX = Keyboard scan state (7B74)
7B98 LD BC,$FEFE Start with the CAPS SHIFT-V half-row
7B9B IN A,(C) Read it and hide the ignored keys
7B9D AND $1F Keep only the bits of $1F
7B9F OR (IX+$00) Combine with (IX+$00)
7BA2 PUSH AF Save AF
7BA3 CPL Any key down now that was up before?
7BA4 AND (HL) Keep only the bits of (HL)
7BA5 CPL A = NOT A
7BA6 JR Z,$7BAF If it is zero, go to 7BAF
7BA8 LD ($7B7C),BC Yes: remember the row and the bits
7BAC LD ($7B7C),A Store A in the new key record
7BAF POP AF Restore AF
7BB0 LD (HL),A Save this reading for next time
7BB1 INC HL Increment HL
7BB2 INC IX Increment IX
7BB4 RLC B Next half-row
7BB6 JR C,$7B9B If carry is set, go to 7B9B
7BB8 LD BC,($7B7C) Was a new key found?
7BBC LD A,B A = B
7BBD OR C Combine with C
7BBE JR Z,$7BE9 If it is zero, go to 7BE9
7BC0 LD A,$FB Work out its number: 5 x row...
7BC2 ADD A,$05 Add A,$05
7BC4 RRC B Shift/rotate B
7BC6 JR C,$7BC2 If carry set, go to 7BC2
7BC8 DEC A Decrement A
7BC9 INC A Increment A
7BCA RRC C ...+ bit
7BCC JR C,$7BC9 If carry set, go to 7BC9
7BCE LD C,A C = A
7BCF LD B,$00 B = 0
7BD1 LD HL,$7BEE Use the normal table...
7BD4 LD A,$FE ...if CAPS SHIFT is pressed...
7BD6 IN A,($FE) Read the keyboard/port
7BD8 AND $01 Keep only the bits of $01
7BDA JR Z,$7BE4 If it is zero, go to 7BE4
7BDC LD A,$7F ...or SYMBOL SHIFT is not
7BDE IN A,($FE) Read the keyboard/port
7BE0 AND $02 Keep only the bits of $02
7BE2 JR NZ,$7BE7 If it is not zero, go to 7BE7
7BE4 LD HL,$7C16 Otherwise use the SYMBOL SHIFT table
7BE7 ADD HL,BC Look up the key
7BE8 LD A,(HL) A = (HL)
7BE9 POP BC Restore BC
7BEA POP IX Restore IX
7BEC POP HL Restore HL
7BED RET Done
Prev: 7B74 Up: Map Next: 7BEE