ZX Basic & reading two keys at the same time

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
MustardTiger
Microbot
Posts: 122
Joined: Tue May 02, 2023 8:05 pm

ZX Basic & reading two keys at the same time

Post by MustardTiger »

Maybe I'm missing something but it doesn't look like you can read more than one key at a time in Basic.

INKEY$ only reads 1

Using IN() can get a row of keys but there's no boolean logic to extract the bits.

I'd like to have a basic program where I can move diagonally with two keys pressed. Is there a way to achieve this?
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: ZX Basic & reading two keys at the same time

Post by Dr beep »

You could use multiple IN's.
So QA56 and M could be used for up/down/left/right/fire.

Within same IN-port first check highest bit (subtract) then test lower bits, but different ports is easier and quicker.
AndyC
Dynamite Dan
Posts: 1408
Joined: Mon Nov 13, 2017 5:12 am

Re: ZX Basic & reading two keys at the same time

Post by AndyC »

One way is to use a small M/C routine via USR to do it for you or to add bitwise capabilities etc. I'm assuming you don't want that.

The ugly way is use four different half rows, so keys like Q,A,P,L and then just use IN to check each one. That doesn't give you nice keyboard options though.

The final way is to use IN but do lots of comparisons against the different values that might occur if a particular key is pressed i.e

LET i = IN(...)
IF i = 1 OR i = 3 OR i = 5... THEN .. up key pressed

Etc

And then curse Sinclair BASIC for being a bit crap
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: ZX Basic & reading two keys at the same time

Post by Dr beep »

AndyC wrote: Thu Jan 04, 2024 2:12 pm The ugly way is use four different half rows, so keys like Q,A,P,L and then just use IN to check each one. That doesn't give you nice keyboard options though.
QA56 M

In my ONELINER FINGERTWISTER I have a nice solution.

You can download it from this site.

https://spectrumcomputing.co.uk/entry/1 ... /ONELINERS
User avatar
WhatHoSnorkers
Manic Miner
Posts: 254
Joined: Tue Dec 10, 2019 3:22 pm

Re: ZX Basic & reading two keys at the same time

Post by WhatHoSnorkers »

MustardTiger wrote: Thu Jan 04, 2024 1:49 pm Maybe I'm missing something but it doesn't look like you can read more than one key at a time in Basic.

INKEY$ only reads 1

Using IN() can get a row of keys but there's no boolean logic to extract the bits.

I'd like to have a basic program where I can move diagonally with two keys pressed. Is there a way to achieve this?
Yes, I typed in a game called "COSMOS" by David Perry, and then changed it so I could move diagonally. I did this with IN like you say. I'll have a look at the source after work and see what exactly I did... I wouldn't have done anything clever with machine code!
I have a little YouTube channel of nonsense
https://www.youtube.com/c/JamesOGradyWhatHoSnorkers
Timmy
Manic Miner
Posts: 230
Joined: Sat Apr 23, 2022 7:13 pm
Location: The Netherlands

Re: ZX Basic & reading two keys at the same time

Post by Timmy »

There are like 40 keys on the keyboard. You could also just assign some other keys for diagonal movement, like some games do?
AndyC
Dynamite Dan
Posts: 1408
Joined: Mon Nov 13, 2017 5:12 am

Re: ZX Basic & reading two keys at the same time

Post by AndyC »

Dr beep wrote: Thu Jan 04, 2024 2:17 pm QA56 M
Are you, by any chance, an octopus? I don't have nearly enough dexterity in my hands to manage that.

QA56 X

Would require a bit less contortion, although I still wouldn't call it nice.
Last edited by AndyC on Thu Jan 04, 2024 2:56 pm, edited 1 time in total.
User avatar
WhatHoSnorkers
Manic Miner
Posts: 254
Joined: Tue Dec 10, 2019 3:22 pm

Re: ZX Basic & reading two keys at the same time

Post by WhatHoSnorkers »

WhatHoSnorkers wrote: Thu Jan 04, 2024 2:19 pm Yes, I typed in a game called "COSMOS" by David Perry, and then changed it so I could move diagonally. I did this with IN like you say. I'll have a look at the source after work and see what exactly I did... I wouldn't have done anything clever with machine code!
The game used A for rows and B for columns.

53 LET A=A+(IN 65022=190 AND A<19) - (IN 65410=190 AND a>3): LET B=B+(IN 57342=190 AND B<21) - (IN 57342=189 AND b>2)
55 IF IN 32766=190 THEN GO SUB 500

So this was Q A O P SPACE.

If I'd gone for Sinclair Joystick keys then I'd have needed to be cleverer.
I have a little YouTube channel of nonsense
https://www.youtube.com/c/JamesOGradyWhatHoSnorkers
User avatar
MustardTiger
Microbot
Posts: 122
Joined: Tue May 02, 2023 8:05 pm

Re: ZX Basic & reading two keys at the same time

Post by MustardTiger »

WhatHoSnorkers wrote: Thu Jan 04, 2024 2:30 pm The game used A for rows and B for columns.

53 LET A=A+(IN 65022=190 AND A<19) - (IN 65410=190 AND a>3): LET B=B+(IN 57342=190 AND B<21) - (IN 57342=189 AND b>2)
55 IF IN 32766=190 THEN GO SUB 500

So this was Q A O P SPACE.

If I'd gone for Sinclair Joystick keys then I'd have needed to be cleverer.
That looks like a good place to start. Thanks
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: ZX Basic & reading two keys at the same time

Post by Dr beep »

AndyC wrote: Thu Jan 04, 2024 2:24 pm At you, by any chance, an octopus? I don't have nearly enough dexterity in my hands to manage that.

QA56 X

Would require a bit less contortion, although I still wouldn't call it nice.
QA56Z where normally QAOPZ is used.
User avatar
Stefan
Manic Miner
Posts: 809
Joined: Mon Nov 13, 2017 9:51 pm
Location: Belgium
Contact:

Re: ZX Basic & reading two keys at the same time

Post by Stefan »

MustardTiger wrote: Thu Jan 04, 2024 1:49 pm Using IN() can get a row of keys but there's no boolean logic to extract the bits.
Tss...

Code: Select all

10 poke 16384,in(254):for b=0 to 7:print at b,1;b;" ";point(b,175):next b:goto 10
Last edited by Stefan on Thu Jan 04, 2024 2:57 pm, edited 1 time in total.
User avatar
MustardTiger
Microbot
Posts: 122
Joined: Tue May 02, 2023 8:05 pm

Re: ZX Basic & reading two keys at the same time

Post by MustardTiger »

Stefan wrote: Thu Jan 04, 2024 2:52 pm Tss...

Code: Select all

10 poke 16384,in(254):for b=0 to 7:print at 0,b;b;" ";point(0,b):next b:goto 10
Cannot test this at the moment, so may contain syntax errors and reversed x and y coordinates.
amazing :lol:
User avatar
Stefan
Manic Miner
Posts: 809
Joined: Mon Nov 13, 2017 9:51 pm
Location: Belgium
Contact:

Re: ZX Basic & reading two keys at the same time

Post by Stefan »

MustardTiger wrote: Thu Jan 04, 2024 2:57 pm amazing :lol:
:D updated the code and it actually works - although the bits may still be reversed from what you would normally expect.
User avatar
MustardTiger
Microbot
Posts: 122
Joined: Tue May 02, 2023 8:05 pm

Re: ZX Basic & reading two keys at the same time

Post by MustardTiger »

WhatHoSnorkers wrote: Thu Jan 04, 2024 2:30 pm The game used A for rows and B for columns.

53 LET A=A+(IN 65022=190 AND A<19) - (IN 65410=190 AND a>3): LET B=B+(IN 57342=190 AND B<21) - (IN 57342=189 AND b>2)
55 IF IN 32766=190 THEN GO SUB 500

So this was Q A O P SPACE.

If I'd gone for Sinclair Joystick keys then I'd have needed to be cleverer.
This works, kindof. 65410 is 64510 (no big deal) but the 190s had to be 254. Not sure why bit 6 is clear in those values. I have a vague memory of different spectrums having unused bits set differently (could be thinking of something completely different tho)
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: ZX Basic & reading two keys at the same time

Post by Dr beep »

MustardTiger wrote: Thu Jan 04, 2024 3:00 pm This works, kindof. 65410 is 64510 (no big deal) but the 190s had to be 254. Not sure why bit 6 is clear in those values. I have a vague memory of different spectrums having unused bits set differently (could be thinking of something completely different tho)
191 or 255 for no key depends on the issue you play on.
Again see my ONELINER to make it issue independent.
User avatar
MustardTiger
Microbot
Posts: 122
Joined: Tue May 02, 2023 8:05 pm

Re: ZX Basic & reading two keys at the same time

Post by MustardTiger »

Dr beep wrote: Thu Jan 04, 2024 3:03 pm 191 or 255 for no key depends on the issue you play on.
Again see my ONELINER to make it issue independent.
I had a look but the listing is a huge wall of text ;) What line number specifically?
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: ZX Basic & reading two keys at the same time

Post by Dr beep »

MustardTiger wrote: Thu Jan 04, 2024 3:06 pm I had a look but the listing is a huge wall of text ;) What line number specifically?
TWISTER is game 32 so line 64
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: ZX Basic & reading two keys at the same time

Post by Dr beep »

Line 42 (TANK BATTLE) is even better for IN use.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: ZX Basic & reading two keys at the same time

Post by ParadigmShifter »

This reads the status of all pressed keys into 40 bytes from 65000 to 650039 and there's a craptastic demo in basic.

Image

The ordering is a bit weird, bytes from 65000 up order correspond to

caps shift, ZXCV
ASDFG
QWERT
12345
09876
POIUY
enter, LKJH
space, symbol shift, MNB

1 = pressed
0 = not pressed

enjoy

source:

Code: Select all

	ORG 65000

kbdbuff BLOCK 40

read_keys:
	ld hl, kbdbuff
	ld bc, #fefe

.nexthalfline
	in a, (c)
	cpl
	and #1f
	ld e, a
	ld d, 5

.loop
	xor a
	rr e
	adc a
	ld (hl), a
	inc hl

	dec d
	jr nz, .loop

	rlc b
	jr c, .nexthalfline
	ret
If it stomps all over UDGs that might be an issue though lol ;) I don't know where the UDGs live. If you want me to assemble it to a different ORG I can I suppose.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: ZX Basic & reading two keys at the same time

Post by ParadigmShifter »

Less crap demo (only a bit less crap though). ^ = caps shift, $ = symbol shift, _ = space, > = enter

Obviously the routine can be used as a basis for redefine keys and can read any key. It's the BASIC code that slows it down lol, obviously you won't be reading the status of all 40 keys and displaying what you pressed most of the time.

Image

EDIT: I think line 20 should really have GOTO 10 at the end too ;) Not that it matters it will just print an extra space I think.

If you change it to print "." instead of space when nothing is pressed it's more exciting I guess. Still slow though.

The routine is relocatable you just need to change the 2nd and 3rd byte of the DATA statement to point at the ORG address

Currently that is 65000 = #FDE8 so the 2nd and 3rd bytes are #E8, #FD = 232, 253. Change to ORG ADDRESS (= CLEAR address + 1) MOD 256 second byte, ORG ADDRESS / 256 third byte.

65000 MOD 256 = 232
65000 /256 = 253

And you need to POKE ORG ADDRESS + 40 to ORG ADDRESS + 67 when you read the machine code from the data statement.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: ZX Basic & reading two keys at the same time

Post by ParadigmShifter »

New version

Image

USR 65000 now returns number of keys pressed so you can skip processing if nothing is pressed. Demo program only updates if number of pressed keys changes (which isn't great because it is possible you release a key and press another on the same call but never mind you get the point).

New source code

Code: Select all

	ORG 65000

kbdbuff BLOCK 40

read_keys:
	ld hl, kbdbuff
	ld bc, #fefe

.nexthalfline
	in a, (c)
	cpl
	and #1f
	ld e, a
	ld d, 5

.loop
	xor a
	rr e
	adc a
	ld (hl), a
	inc hl

	dec d
	jr nz, .loop

	rlc b
	jr c, .nexthalfline

	ld hl, kbdbuff
	xor a
	ld b, a
	ld b, 40
.count
	add (hl)
	inc hl
	djnz .count
	ld c, a

	ret
You have to poke the org address in 2 different places though if you want to relocate it :( I could get around that by PUSH HL when I first set it to kbdbuff and POP it where I set it again but I didn't, sorry ;)

EDIT: stupid waste of a byte - djnz finishes with b=0 and setting b to 0 then setting it to 40 immediately after isn't too clever lol
User avatar
MustardTiger
Microbot
Posts: 122
Joined: Tue May 02, 2023 8:05 pm

Re: ZX Basic & reading two keys at the same time

Post by MustardTiger »

This is what I've come up with based on Dr Beeps code.

Image

Thanks ParadigmShifter for the assembler version. UDGs are at65368 and above so no worries there.
Post Reply