| The Hobbit (v1.0) | Routines |
| Prev: 7B74 | Up: Map | Next: 7BEE |
|
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.
|
||||||||
| 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 |