This code appears in the following versions (click to see it in the source code):
Code variations between these versions are shown below.
Code variation 1 of 6A variation in the comments only
Tap on a block to expand it, and tap it again to revert.
Name: DKS4Name: DKS5
Code variation 2 of 6A variation in the comments only
Tap on a block to expand it, and tap it again to revert.
Type: SubroutineType: Macro
Category: Keyboard Summary: Scan the keyboard to see if a specific key is being pressed Deep dive: The key logger
Arguments:
Code variation 3 of 6A variation in the comments only
Tap on a block to expand it, and tap it again to revert.
X The internal number of the key to check (see p.142 of the Advanced User Guide for a list of internal key numbers)A The internal number of the key to check (see p.142 of the Advanced User Guide for a list of internal key numbers)X The internal number of the key to check (see p.40 of the Electron Advanced User Guide for a list of internal key numbers)
Returns: A If the key in A is being pressed, A contains the original argument A, but with bit 7 set (i.e. A + 128). If the key in A is not being pressed, the value in A is unchanged
Code variation 4 of 6A variation in the comments only
This variation is blank in the 6502 Second Processor version.
X Contains the same as A
Code variation 5 of 6A variation in the comments only
This variation is blank in the Cassette, Disc (flight), Disc (docked), 6502 Second Processor and Master versions.
Other entry points: CAPSL Scan the keyboard to see if CAPS LOCK is being pressed
Code variation 6 of 6Minor and very low-impact
Tap on a block to expand it, and tap it again to revert.
.DKS4 LDA #%00000011 \ Set A to %00000011, so it's ready to send to SHEILA \ once interrupts have been disabled SEI \ Disable interrupts so we can scan the keyboard \ without being hijacked STA VIA+&40 \ Set 6522 System VIA output register ORB (SHEILA &40) \ to %00000011 to stop auto scan of keyboard LDA #%01111111 \ Set 6522 System VIA data direction register DDRA STA VIA+&43 \ (SHEILA &43) to %01111111. This sets the A registers \ (IRA and ORA) so that: \ \ * Bits 0-6 of ORA will be sent to the keyboard \ \ * Bit 7 of IRA will be read from the keyboard STX VIA+&4F \ Set 6522 System VIA output register ORA (SHEILA &4F) \ to X, the key we want to scan for; bits 0-6 will be \ sent to the keyboard, of which bits 0-3 determine the \ keyboard column, and bits 4-6 the keyboard row LDX VIA+&4F \ Read 6522 System VIA output register IRA (SHEILA &4F) \ into X; bit 7 is the only bit that will have changed. \ If the key is pressed, then bit 7 will be set, \ otherwise it will be clear LDA #%00001011 \ Set 6522 System VIA output register ORB (SHEILA &40) STA VIA+&40 \ to %00001011 to restart auto scan of keyboard CLI \ Allow interrupts again TXA \ Transfer X into A RTS \ Return from the subroutineIF _SNG47 .DKS5 LDX #3 \ Set X to 3, so it's ready to send to SHEILA once \ interrupts have been disabled SEI \ Disable interrupts so we can scan the keyboard \ without being hijacked STX VIA+&40 \ Set 6522 System VIA output register ORB (SHEILA &40) \ to %00000011 to stop auto scan of keyboard LDX #%01111111 \ Set 6522 System VIA data direction register DDRA STX VIA+&43 \ (SHEILA &43) to %01111111. This sets the A registers \ (IRA and ORA) so that: \ \ * Bits 0-6 of ORA will be sent to the keyboard \ \ * Bit 7 of IRA will be read from the keyboard STA VIA+&4F \ Set 6522 System VIA output register ORA (SHEILA &4F) \ to A, the key we want to scan for; bits 0-6 will be \ sent to the keyboard, of which bits 0-3 determine the \ keyboard column, and bits 4-6 the keyboard row LDX VIA+&4F \ Read 6522 System VIA output register IRA (SHEILA &4F) \ into X; bit 7 is the only bit that will have changed. \ If the key is pressed, then bit 7 will be set, \ otherwise it will be clear LDA #%00001011 \ Set 6522 System VIA output register ORB (SHEILA &40) STA VIA+&40 \ to %00001011 to restart auto scan of keyboard CLI \ Allow interrupts again TXA \ Transfer X into A RTS \ Return from the subroutine ENDIFMACRO DKS4 LDX #3 \ Set X to 3, so it's ready to send to SHEILA once \ interrupts have been disabled SEI \ Disable interrupts so we can scan the keyboard \ without being hijacked STX VIA+&40 \ Set 6522 System VIA output register ORB (SHEILA &40) \ to %00000011 to stop auto scan of keyboard LDX #%01111111 \ Set 6522 System VIA data direction register DDRA STX VIA+&43 \ (SHEILA &43) to %01111111. This sets the A registers \ (IRA and ORA) so that: \ \ * Bits 0-6 of ORA will be sent to the keyboard \ \ * Bit 7 of IRA will be read from the keyboard STA VIA+&4F \ Set 6522 System VIA output register ORA (SHEILA &4F) \ to A, the key we want to scan for; bits 0-6 will be \ sent to the keyboard, of which bits 0-3 determine the \ keyboard column, and bits 4-6 the keyboard row LDA VIA+&4F \ Read 6522 System VIA output register IRA (SHEILA &4F) \ into A; bit 7 is the only bit that will have changed. \ If the key is pressed, then bit 7 will be set, \ otherwise it will be clear LDX #%00001011 \ Set 6522 System VIA output register ORB (SHEILA &40) STX VIA+&40 \ to %00001011 to restart auto scan of keyboard CLI \ Allow interrupts again ENDMACRO.KSCAN \ This routine is called from below, and performs the \ actual keyboard scan SEC \ Set the C flag and clear the V flag, so when we call CLV \ KEYV, it scans the keyboard just like OSBYTE 121 SEI \ Disable interrupts JMP (S%+4) \ Jump to the original value of KEYV, which is stored in \ S%+4. Because we set the C and V flags as above, this \ will scan the keyboard like OSBYTE 121, which expects \ X to be set to the internal key number to scan for, \ EOR'd with %10000000. Unlike OSBYTE 121, a direct call \ to KEYV will return negative value in both A and X if \ that key is being pressed .CAPSL LDX #&40 \ Set X to the internal key number for CAPS LOCK, and \ fall through into DKS4 to check whether it is being \ pressed .DKS4 TYA \ Store Y on the stack so we can retrieve it when we PHA \ return from the subroutine, thus preserving Y TXA \ Store the key number to check in X on the stack so PHA \ we can retrieve it below ORA #%10000000 \ Set bit 7 of the key to check for and transfer the TAX \ value to X JSR KSCAN \ Call KSCAN to check whether the key in X is being \ pressed, which returns a negative value in A and X \ if it is CLI \ Enable interrupts again (as they are disabled in \ KSCAN) TAX \ Set X to the result of the key press call above PLA \ Fetch the original argument value of X from the stack AND #%01111111 \ into A, and clear bit 7 CPX #%10000000 \ If bit 7 of the result of the key press check above is BCC P%+4 \ set, then the key in X is being pressed, so skip the \ next instruction ORA #%10000000 \ The key in X isn't being pressed, so set bit 7 of A TAX \ By this point, A contains the key number we wanted to \ check for, with bit 7 set if the key is being pressed \ and clear otherwise, which is what we want to return \ from the subroutine, but first we need to restore the \ value of Y from the stack, so we store the result A in \ X while we do that PLA \ Restore the value Y that we stored on the stack, so it TAY \ gets preserved across calls to the subroutine TXA \ And we now retrieve the result that we stored in X \ back into A, so we can return it RTS \ Return from the subroutine