Page 2 of 3

Re: Machine Code Keyboard Input

Posted: Thu Aug 04, 2022 7:22 pm
by dr beep
MrVertigo wrote: Thu Aug 04, 2022 6:04 pm Ah, I understood the keyboard stuff before, but I couldn’t understand where FE was coming from in the stuff I was reading. I didn’t realise it was the ULA.

I sometimes see programmes doing a compare for 191, from different half row scans, checking for ANY key from that half row. But I don’t understand why 191. What is the reason? I understand that a key press, any key press, will turn one of the 1s to a 0. But surely only one of the keys will give 1011111 (191)?
I would like an example of what you mean. Ie I use LASTK todo a quick test if Newline (but also H to Newline) is pressed with 191.

You can test a single key
with this code

Code: Select all

AGAIN:
LD A,%11111110 ; Shift to V
IN A,(254) ; read this row
AND %00000010  ; Test for Z
JR NZ,AGAIN ; Wait for Z is pressed
You can do the same with all keys.
Select any row in the LD A,%11111110, just set 0 to bit to activate a row to read
IN the AND select the bit matching the key.

Advantage of using IN is that you can read diagonal move as well

Re: Machine Code Keyboard Input

Posted: Thu Aug 04, 2022 7:42 pm
by MrVertigo
Here is a little example where I am not understanding why 191 is used in both compares:

ld bc,65278 ;read keyboard caps to v
in a,(c)
cp 191
jr nz, moveright
inc l
moveright
ld bc,32766 ;read keyboard space to b
in a,(c)
cp 191
jr nz, dontmove
dec l
dontmove

Re: Machine Code Keyboard Input

Posted: Thu Aug 04, 2022 8:15 pm
by dr beep
MrVertigo wrote: Thu Aug 04, 2022 7:42 pm Here is a little example where I am not understanding why 191 is used in both compares:

ld bc,65278 ;read keyboard caps to v
in a,(c)
cp 191
jr nz, moveright
inc l
moveright
ld bc,32766 ;read keyboard space to b
in a,(c)
cp 191
jr nz, dontmove
dec l
dontmove
This must be an example for the ZX Spectrum and even then it is a bad program.
Not all issues will return a value 191 for NOKEY, some issues return 255.
Best to add a AND 31 and test the valuu 31.

A ZX81 will always return 127 when no key is pressed.
A SAM Coupe uses the same technic but will return 95 for no key.
All have in common that the 5 lower bits hold the key pressed, therefore AND 31 to keep those keys only
or just test a single key like my example earlier.

Re: Machine Code Keyboard Input

Posted: Thu Aug 04, 2022 9:20 pm
by MrVertigo
You are right, I think this is for the Spectrum. But am I misunderstanding what is happening in it? I thought if a key is pressed, that puts 191 in the accumulator, so the onscreen position of the graphic (stored at hl) is incremented or decremented, because cp sets the zero flag, passing over the jump command. And if a key is not pressed, 191 doesn’t go into the accumulator, cp doesn’t set the zero flag, and the jump occurs, resulting in the onscreen graphic staying at the same position.

Am I misunderstanding it? Is it NOT pressing a key that is sending 191 to A?

Re: Machine Code Keyboard Input

Posted: Thu Aug 04, 2022 9:39 pm
by dr beep
MrVertigo wrote: Thu Aug 04, 2022 9:20 pm You are right, I think this is for the Spectrum. But am I misunderstanding what is happening in it? I thought if a key is pressed, that puts 191 in the accumulator, so the onscreen position of the graphic (stored at hl) is incremented or decremented, because cp sets the zero flag, passing over the jump command. And if a key is not pressed, 191 doesn’t go into the accumulator, cp doesn’t set the zero flag, and the jump occurs, resulting in the onscreen graphic staying at the same position.

Am I misunderstanding it? Is it NOT pressing a key that is sending 191 to A?
On the ZX Spectrum reading the keyboard will also read the bit for the tape.

So IN A,(254) will read tape in bit 6 and 5 keys in bit 0 to bit 4.
Depending the issue bit 6 is set high or low.
When a key is pressed a bit in range 0..4 is reset and becomes 0.
When NO KEY is pressed all bits are set to 1 and bit 6 MIGHT be reset depending the machine.
On a ZX81 this will be 011 11111
On a ZX Spectrum this is 1X1 11111
On a SAM this is 010 11111

CP sets the zero flag when the result matches the test.

Re: Machine Code Keyboard Input

Posted: Thu Aug 04, 2022 10:32 pm
by MrVertigo
Brilliant. Thank you.

Re: Machine Code Keyboard Input

Posted: Thu Aug 04, 2022 11:06 pm
by mrtinb
Most of the time it’s best just to read LAST_K. Because when you create your own routine, it might work fine for you, but not work so well on real hardware or another emulator.

Re: Machine Code Keyboard Input

Posted: Fri Aug 05, 2022 12:18 am
by MrVertigo
That’s a good point. But doesn’t Lastk preclude simultaneous inputs, meaning you can’t make a character run and jump at the same time, for example?

Re: Machine Code Keyboard Input

Posted: Fri Aug 05, 2022 12:47 am
by 1024MAK
If you go to this web page it summarises the ULA input port on the ZX81 and ZX Spectrum.

The input port handles multiple functions, not just the keyboard. The keyboard uses five data bits: 4, 3, 2, 1 and 0.
As bits 7, 6 and 5 are used for other functions or are unused, they cannot be guaranteed to always be in a known state.

For example on a ZX81/Timex TS1000

Code: Select all

  0-4  Keyboard column bits (0=Pressed)
  5    Not used             (1)
  6    Display Refresh Rate (0=60Hz normally TS1000 or USA ZX81, 1=50Hz normally European ZX81)
  7    Cassette input       (0=Normal, 1=Pulse)
On a ZX Spectrum:

Code: Select all

  0-4  Keyboard Inputs (0=Pressed, 1=Released)
  5    Not used
  6    EAR Input (depends on the ULA version and the state of the MIC & bleeper sound output bits)
  7    Not used

Hence a wise programmer will do as dr beep says, and mask out the unwanted bits, by using AND 31. Then the result is not affected by the state of bits 5 to 7 ;-)

Mark

Re: Machine Code Keyboard Input

Posted: Fri Aug 05, 2022 2:28 am
by MrVertigo
Thanks for this 🙏