MZ-80k – KBD scanning

Independent Key-Scanning on SHARP’s

Written by Sean Wallis  
Source: SUC-magazine July 2001, Volume 21, Number 2, p. 8 – 9 
Independent Key Scanning on the MZ-80K, MZ-80A & MZ-700
Reprinted with minor alterations from SUC-magazine Volume 5, No. 2, March 1986

One of the main problems with SHARP games software is that it is impossible to detect several keys at once using ROM routines; they use a system of preference to decide which key is detected in preference to another. If you use the method detailed below you will, with some limitations, be able to detect any key separately from any other, and hence allow decent keyboard control.

The 8255 PPI chip 

This chip is controlled, for our purposes, via addresses $E000 ( 57344D, keyboard strobe – PPI input ) and $E001 ( 57345D, keyboard receive, PPI output ). To indicate which SET of keys is to be scanned, a number in the range $E0 – $E9 is sent to the PPI input by the command LD ($E000),A. There is then a slight delay while the actual scan takes place, and to allow for this delay a NOP must be inserted in the routine. You can then obtain the status of the specified SET of keys by reading 1 byte from the PPI output using the instruction LD A, ($E001). To check a specific key from this set of keys the appropriate bit must be isolated using either a bogical AND, or a BIT operator; if the bit is 0 then that particular key is pressed, if the bit is 1 it is not pressed.

Implementing independent key scanning in WICS BASIC

In WICS BASIC, to scan for a particular key:

1000 POKE $E000,244: IF (PEEK($E001) AND 1) =0 THEN GOSUB 5000

Here, ‘244‘ selects the group of keys that is to be scanned, and the operation ‘AND 1‘ selects the actual key that is to be tested.

Implementation in SP- and SA-BASICs

If you attempt the same code in SP-5025 or one of its relatives, it won‘t work. This is due to the interpreter scanning for BREAK, which goes through the 8255 and thus upsets any scanning you may attempt via BASIC commands. Therefore you must use machine-code:

 10 GOSUB 10000:REM ** Read machine code into memory **
 100 POKE KY+1,244:POKE KY+10, 1:USR(KY):REM ** Read key **
 110 IF PEEK(53427)=0 THEN GOSUB 5000

 10000 KY=53200:LIMIT=KY - 1
 10010 FOR I = KY TO KY+14
 10020 READ A:POKIE I,A:NEXT :REM put m/c routine into memory at KY:
 10030 DATA 62,240:REM LD A,240
 10040 DATA 50,0,224 :REM LD($E000),A
 10050 DATA 0 :REM NOP
 10060 DATA 58,1,22 :REM LD A,($E001)
 10070 DATA 230,1 :REM AND 1
 10080 DATA 50,255,207 :REM LD (53247),A
 10090 DATA 201 :REM RET
 10100 RETURN

All the examples above show the basic principles of independent key-scanning ( the subroutine at 5000 does whatever you want to do if the desired key is being pressed ). Note that the values 240 and 1 in the m/c subroutine are ‘dummies‘ – the actual values used by the program are set by the POKE KY+ statements in LINE 100. The first POKE sets the group of keys to be scanned, and the second POKE selects the actual key that is to be checked.

If you are using S-BASIC you will need to ‘Page In‘ the 8255 chip addresses in the $E000 area. This requires an OUT ($E3),A instruction before accessing the PPI ( there is no need to ‘Page Out‘ the 8255 chip after the keyscan; this happens automatically when you RETURN from machine-code to BASIC ). So in S-BASIC the program should be amended in 3 places:

 100 POKE KY+3,244:POKE KY+ 12,1 :USR(KY) :REM new POKE addresses
 10010 FOR 1 = KY TO KY + 16 :REM 2 more bytes to copy
 10025 DATA 211,227:.REM code for OUT ($E3), A


There is a slight hang-up when using the 8255 PPI chip for keyboard management. The problem, in general terms, is that if you press several keys simultaneously, the chip may be confused into thinking that others are also pressed. On the MZ-80K, on account of the simple keyboard matrix, it only affects keys next to each other in the same row; on other computers that use the 8255 for keyboard management ( e.g. MSX, Amstrad ) the problem is confused by more complicated keyboard matrices, and you can only experiment. This is a hardware problem to which there is no ideal software solution; just use keyboard combinations that you know work.

The Keyboard Maps

On each map, the X-value at the head of each column is the value to use to test the key bit for that column; and the Y-value at the start of each row is the value that should be sent to $E000 to strobe that row.

On each map there are a few positions that are not connected to any key; each such position is shown by a group of 8 asterisks:


Key-Scanning on the MZ-80B

There is no keyboard map for the MZ-80B, as I have not been able to find the information required. But if Sharp are consistent, the procedures that work on the MZ-80K, MZ-80A and MZ-700 should also work, in principle, on the MZ-80B, and the main differences will be in the keyboard layout. My guess is that addressing locations $E000 and $E001 will have a similar effect. All that is needed is for some daring ‘B‘ owner to construct a keyboard map and send it to the S.U.C. So come on, you ‘B‘ lot, I have given you enough info to get you started, the rest is up to you!

Click here to read more about the key scanning of the MZ-80B and MZ-2500.

Select the MZ-type now to get the MZ-80KMZ-80AMZ-80BMZ-700MZ-800, or MZ-2500 keyboard map.