ZX Basic & reading two keys at the same time
- MustardTiger
- Microbot
- Posts: 122
- Joined: Tue May 02, 2023 8:05 pm
ZX Basic & reading two keys at the same time
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?
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?
Re: ZX Basic & reading two keys at the same time
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.
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.
Re: ZX Basic & reading two keys at the same time
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
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
Re: ZX Basic & reading two keys at the same time
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
- WhatHoSnorkers
- Manic Miner
- Posts: 254
- Joined: Tue Dec 10, 2019 3:22 pm
Re: ZX Basic & reading two keys at the same time
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!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?
I have a little YouTube channel of nonsense
https://www.youtube.com/c/JamesOGradyWhatHoSnorkers
https://www.youtube.com/c/JamesOGradyWhatHoSnorkers
Re: ZX Basic & reading two keys at the same time
There are like 40 keys on the keyboard. You could also just assign some other keys for diagonal movement, like some games do?
Re: ZX Basic & reading two keys at the same time
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.
- WhatHoSnorkers
- Manic Miner
- Posts: 254
- Joined: Tue Dec 10, 2019 3:22 pm
Re: ZX Basic & reading two keys at the same time
The game used A for rows and B for columns.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!
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
https://www.youtube.com/c/JamesOGradyWhatHoSnorkers
- MustardTiger
- Microbot
- Posts: 122
- Joined: Tue May 02, 2023 8:05 pm
Re: ZX Basic & reading two keys at the same time
That looks like a good place to start. ThanksWhatHoSnorkers 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.
Re: ZX Basic & reading two keys at the same time
Tss...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.
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.
- MustardTiger
- Microbot
- Posts: 122
- Joined: Tue May 02, 2023 8:05 pm
Re: ZX Basic & reading two keys at the same time
amazingStefan wrote: ↑Thu Jan 04, 2024 2:52 pm Tss...
Cannot test this at the moment, so may contain syntax errors and reversed x and y coordinates.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
Re: ZX Basic & reading two keys at the same time
updated the code and it actually works - although the bits may still be reversed from what you would normally expect.
- MustardTiger
- Microbot
- Posts: 122
- Joined: Tue May 02, 2023 8:05 pm
Re: ZX Basic & reading two keys at the same time
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)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.
Re: ZX Basic & reading two keys at the same time
191 or 255 for no key depends on the issue you play on.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)
Again see my ONELINER to make it issue independent.
- MustardTiger
- Microbot
- Posts: 122
- Joined: Tue May 02, 2023 8:05 pm
Re: ZX Basic & reading two keys at the same time
TWISTER is game 32 so line 64MustardTiger 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?
Re: ZX Basic & reading two keys at the same time
Line 42 (TANK BATTLE) is even better for IN use.
- ParadigmShifter
- Manic Miner
- Posts: 671
- Joined: Sat Sep 09, 2023 4:55 am
Re: ZX Basic & reading two keys at the same time
This reads the status of all pressed keys into 40 bytes from 65000 to 650039 and there's a craptastic demo in basic.
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:
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.
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
- ParadigmShifter
- Manic Miner
- Posts: 671
- Joined: Sat Sep 09, 2023 4:55 am
Re: ZX Basic & reading two keys at the same time
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.
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.
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.
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.
- ParadigmShifter
- Manic Miner
- Posts: 671
- Joined: Sat Sep 09, 2023 4:55 am
Re: ZX Basic & reading two keys at the same time
New version
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
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
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
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
- MustardTiger
- Microbot
- Posts: 122
- Joined: Tue May 02, 2023 8:05 pm