The Spectrum keyboard can be read from the following Z80 ports:

Bits are set to 0 for any key that is pressed and 1 for any key that is not pressed. Multiple key presses can be read simultaneously.

To read the QWERT row and test for Q, you could do something like this:

LD BC,&FBFE        ; Load BC with the row port address
IN A,(C)           ; Read the port into the accumulator
AND %00000001      ; Mask out the key we are interested in
JR Z,Q_KEY_PRESSED ; If the result is zero, then the key has been pressed...

So, going on from that, here is a keyboard read routine that will return a keypress. It doesn’t do anything clever and will return the first key found if multiple keys are pressed, but it’s a start and probably good enough for front end pages, and so on…

Read_Keyboard:		LD HL,Keyboard_Map		; Point HL at the keyboard list
					LD D,8					; This is the number of ports (rows) to check
					LD C,&FE				; C is always FEh for reading keyboard ports
Read_Keyboard_0:	LD B,(HL)				; Get the keyboard port address from table
					INC HL					; Increment to list of keys
					IN A,(C)				; Read the row of keys in
					AND &1F					; We are only interested in the first five bits
					LD E,5					; This is the number of keys in the row
Read_Keyboard_1:	SRL A					; Shift A right; bit 0 sets carry bit
					JR NC,Read_Keyboard_2	; If the bit is 0, we've found our key
					INC HL					; Go to next table address
					DEC E					; Decrement key loop counter
					JR NZ,Read_Keyboard_1 	; Loop around until this row finished
					DEC D					; Decrement row loop counter
					JR NZ,Read_Keyboard_0	; Loop around until we are done
					AND A					; Clear A (no key found)
Read_Keyboard_2:	LD A,(HL)				; We've found a key at this point; fetch the character code!

Keyboard_Map:		DB &FE,"#","Z","X","C","V"
					DB &FD,"A","S","D","F","G"
					DB &FB,"Q","W","E","R","T"
					DB &F7,"1","2","3","4","5"
					DB &EF,"0","9","8","7","6"
					DB &DF,"P","O","I","U","Y"
					DB &BF,"#","L","K","J","H"
					DB &7F," ","#","M","N","B"