CPC Guide - Reading the keyboard and JoysticksScanning the Keybord and Joysicks The keyboard and joysticks are scanned using the PSG and the 8255 PPI. It is necessary that you understand how to use these before you continue to read this part. The keys on the keyboard and the joysticks are arranged in an 8 by 10 matrix. The matrix consists of 10 bytes. (each of which is called a line). Each of these lines has a bit set aside to a particular key. (Therefore allowing 80 possible keys to be read) When the keyboard is read, a particular bit is 0 or 1 depending on whether the key has been pressed. If the value is 0, the key has been pressed, if the value is 1, the key has not been pressed. The joysticks are also scanned via the matrix. Joystick 0 occupies it's own space in the matrix, but joystick 1 occupies space already used for the keyboard. It is entirely possible to simulate the state of joystick 1 by pressing the appropiate keys on the keyboard. Keyboard clash There is a peculiarity when scanning the keyboard. If you press three keys in a 2 by 2 block together, you will get the other key in the block. i.e. if you press J,F and B you will get N, and similarly if you press J,K and L you will get H. NOTE: This effect also occurs at the edges. i.e. if you press V,X and 4 you will get 6. And if you press Down and left on the joystick and right arrow key is pressed, you will get Down arrow produced. Another thing, this affect is not confined to keys in a 2 by 2 block together. i.e. if you press W and S and L you will get I. and if you press Q,A and P you will get : . This effect doesn't occur if you press two keys in a vertical next to each other and two in a horizontal next to each other. i.e. if you press W and S and J, you will not get K. These effects cause the keyboard clash which effect many two player games. It doesn't usually effect one player games, so as long as the keys do not clash to give a key wanted, (i.e. pressing Q,A and P gives :, but since most games only use Q,A,O,P and SPACE for control, it doesn't matter that : also occurs.), there is no need to worry about keyboard clash. The only solution is to choose keys which will not clash. The keyboard matrix The position of each key in the keyboard matrix is shown in the diagram below. Bit Keyboard Line 0 1 2 3 4 5 6 7 8 9 --+-------------------------------------------------------------------- 7 | f. f0 Ctrl > < Space V X Z Del | . , --+-------------------------------------------------------------------- 6 | Enter f2 ` ? M N B C Caps Spare | \ / Lock --+-------------------------------------------------------------------- 5 | f3 f1 Shift * K J F D A Joy 0 | : Fire 1 --+-------------------------------------------------------------------- 4 | f6 f5 f4 + L H G S Tab Joy 0 | ; Fire 2 --+-------------------------------------------------------------------- 3 | f9 f8 } P I Y T W Q Joy 0 | ] Right --+-------------------------------------------------------------------- 2 | Curs f7 Ret- | O U R E Esc Joy 0 | Down urn @ Left --+-------------------------------------------------------------------- 1 | Curs Copy { = ) ' % # " Joy 0 | Right [ - 9 7 5 3 2 Down --+-------------------------------------------------------------------- 0 | Curs Curs Clr £ _ ( & $ ! Joy 0 | Up Left ^ 0 8 6 4 1 Up --+-------------------------------------------------------------------- Note: 1) Joystick 1 is mapped onto line 6. When checking Line 6 becomes: Bit 7: Spare Bit 6: Spare Bit 5: Joy 1 Fire 1 Bit 4: Joy 1 Fire 2 Bit 3: Joy 1 Right Bit 2: Joy 1 Left Bit 1: Joy 1 Down Bit 0: Joy 1 Up 2) Bit 6 on the joystick lines (line 9 and 6), may be used as the middle button on an AMX compatible mouse. 3) Those keys prefixed with an f are located on the keypad. (464 users) 4) For CPC464 users, ENTER refers to the small Enter key, and RETURN refers to the large enter key. 5) The hardware does allow keyboard lines 11,12,13 and 14 to be selected. After testing on a real CPC, it is found that these never change, they always return &FF. 6) Finally, DON'T FORGET THE DREADED KEYBOARD CLASH with combinations of keys! Reading the keyboard and Joysticks As mentioned before the keyboard and joysticks are scanned using the PSG and the 8255 PPI. The PSG is used to read the keyboard line (using port A of the PSG; register 14) and port &F6xx of the 8255 PPI. The keyboard line (in the range 0-10) is put into port &F6xx of the PPI. The data on the keyboard line will now be present in register 14 of the PSG. Before the data can be read we must make sure Port A of the PSG is acting in input mode. This is done by setting bit 6 of the mixer register (of the PSG) to 0. Normally, port A is programmed for input unless it has been changed by the user. If it has not been changed it is not necessary to put this into the keyboard scanning routine. Once this is done, we can select register 14 and read the value from it. See programming the PSG for more information. (Note: when you are sending control information to the PSG using port &F6xx it is important to change bits 6 and 7 only, otherwise the wrong keyboard line will be read). This process is repeated until all keyboard lines are read. This allows you the flexability to read one,two or all of the keyboard lines. When all reading has been done, port &F4xx of the 8255 PPI must be returned to output mode (so that the PSG can be used), and the PSG must be sent inactive. Example: (Assuming port A of the PSG is acting as input,port B is input and port C is output). In this example, we will only be reading one line of the keyboard. A will contain the keyboard data from keyboard line 9. DEL_flag will be 1 if DEL has been pressed, or 0 if DEL has not been pressed. ;; INITIALISE FOR READING ld bc,&f400+14 ;PSG Register 14 (Port A of PSG) out (c),c ;(contains keyboard line data) ld b,&f6 ;PSG control ld c,%11000000 ;Select Register 14 for use out (c),a ;send ld c,0 ;PSG inactive out (c),c ;send ld b,&f7 ;8255 PPI control ld c,%10010010 ;Port A and Port C (upper) - Operating mode 0 ;Port A input, Port C (upper) output. ;Port B and Port C (lower) - Operating mode 0 ;Port B input, Port C (lower) output out (c),c ;send control byte ;;READ KEYBOARD LINE ld b,&F6 ;PSG control + keyboard line wanted ld a,%01000000 ;PSG control - read or 9 ;keyboard line 9 out (c),a ;send it ld b,&F4 ;Port to get PSG port A (register 14) data ;from in a,(c) ;Keyboard data from keyboard line 9 cpl ;turn all 1's to 0's and all 0's to 1's ;so now if a key has been pressed it's bit will ;be 1, and if it has not been pressed it's will ;be 0 bit 7,a ;this bit is used to indicate if DEL has been ;pressed. jr z,DEL_not_pressed ;Since the bit is 0, DEL has not been pressed ld a,1 ;Flag = 1 to indicate DEL pressed ld (DEL_flag),a jr continue .DEL_not_pressed ld a,0 ld (DEL_flag),a ;Flag = 0 to indicate DEL not pressed .continue ;; RESTORE 8255 PORTS TO THEIR ORIGINAL CONDITIONS ld b,&f7 ;8255 Control ld c,%10000010 ;Port A and Port C (upper) - Operating mode 0 ;Port A output, Port C (upper) output. ;Port B and Port C (lower) - Operating mode 0 ;Port B input, Port C (lower) output out (c),c ld b,&f6 ;PSG control ld c,0 ;inactive out (c),c ret .DEL_flag defb 0