Jump to content

Photo

Reading the keyboard in Atari BASIC (no ATASCII needed)

basic

22 replies to this topic

#1 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • 105 posts

Posted Wed Feb 20, 2019 12:15 AM

Hi

 

I am trying to figure out a short and simple way to read the keyboard in plain Atari BASIC with no need to have the ATASCII code.
I just need to detect if some keys are detected.

In a loop I do
...
1300 S=PEEK(764)
1400 if s<>255 THEN ...
1500 POKE 764,255

...

This sort of works but it is not detecting all key-presses...

Is there a better solution?



#2 slx OFFLINE  

slx

    Stargunner

  • 1,749 posts
  • Location:Vienna, Austria

Posted Wed Feb 20, 2019 12:25 AM

Hi
 
I am trying to figure out a short and simple way to read the keyboard in plain Atari BASIC with no need to have the ATASCII code.
I just need to detect if some keys are detected.

In a loop I do
...
1300 S=PEEK(764)
1400 if s<>255 THEN ...
1500 POKE 764,255
...

This sort of works but it is not detecting all key-presses...

Is there a better solution?

You can't detect Shift and Control alone. Is it always the same keys it doesn't detect? Are you trying this on emulation or a real machine?

#3 Rybags ONLINE  

Rybags

    Gridrunner

  • 16,029 posts
  • Location:Australia

Posted Wed Feb 20, 2019 1:12 AM

Due to the matrix layout there's some combinations with Shift+Ctrl that don't register.

 

Code 255 is also returned by Shift+Ctrl+A which is also the initial state and shadow register value for "no key" so is also harder to detect.

 

You can detect Shift on it's own via it's bit in SKCTL - handy for adding extra function to the console keys but rarely used - IIRC Jaggi Lines/ Resue on Fractalus uses it.

But you can't distinguish between left and right Shift.



#4 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Wed Feb 20, 2019 1:45 AM

I don't mind if some key combinations are not registered.
How can I detect all key-presses (not all keys)?

My code does not detect all key-presses. Sometimes you press a key and the key-press is not detected. It is detected if you keep on pressing it.



#5 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Wed Feb 20, 2019 3:31 AM

764 is a shadow register and that is what it is not reliable. Not a hardware issue.
This seems to work better:

 

10 P=PEEK(53769)
20 IF PEEK(753)= 3 THEN PRINT P
30 POKE 764,255
40 GOTO 10

Edited by Fabrizio Caruso, Wed Feb 20, 2019 3:31 AM.


#6 Rybags ONLINE  

Rybags

    Gridrunner

  • 16,029 posts
  • Location:Australia

Posted Wed Feb 20, 2019 5:03 AM

The trick with PEEK(764) - don't POKE 764,255 unless you've processed a keypress and want to clear the current one.

 

BASIC is sufficiently slow that you can easily lose a keypress if you do that.

Also - a single keypress can be buffered so you might want to clear it but in some cases it's desirable to let it through.

 

And, additional to the non-detectables mentioned before, CTRL 1 is used to pause screen output and doesn't get mirrored in the CH shadow.



#7 Rybags ONLINE  

Rybags

    Gridrunner

  • 16,029 posts
  • Location:Australia

Posted Wed Feb 20, 2019 5:14 AM

Quick and dirty subroutine in Basic that allows keypress, console key or SHIFT on it's own.

 

1000 POKE 764,255:REM REMOVE TO ALLOWED BUFFERED KEYPRESS
1010 IF PEEK(764)<>255 THEN 1100
1020 POKE 53279,8:IF PEEK(53279)<>7 THEN 1100
1030 SK=PEEK(53775)
1040 S=SK-(INT(SK/16)*16)
1050 IF S<8 THEN 1100
1060 GOTO 1010
1100 RETURN


#8 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Wed Feb 20, 2019 6:32 AM

Thanks! The problem is that I am doing this for a 10-liner... In other BASIC dialects I need 5 characters "get a$" or 10 characters a$=inkeys$.
I was looking for a short solution and I do not need console kets and shift. I need to detect I J K L SPACE.



#9 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Wed Feb 20, 2019 6:40 AM

@Rybags, does your code get simple if we exclude special keys?

I only need to detect I J K L SPACE or something similar. I need the code to be as short as possible. It is for a 10-liner.



#10 dmsc OFFLINE  

dmsc

    Moonsweeper

  • 499 posts
  • Location:Viņa del Mar, Chile

Posted Wed Feb 20, 2019 9:20 AM

Hi!
 

@Rybags, does your code get simple if we exclude special keys?

I only need to detect I J K L SPACE or something similar. I need the code to be as short as possible. It is for a 10-liner.


In a tenliner, it is better not to read from keyboard ;) , as reading from joystick is shorter ( STICK(0) and STRIG(0) ).

If you really need to read from keyboard, try to arrange your code so that you poke the key just after reading:
 
 k=peek(764):poke764,9:ud=(k=5)-(k=13):lr=(k=0)-(k=1)
Note two things:
- I poke "9" to 764 instead of 255, this is shorter and there is no key with code 9.
- I use a comparison in an expression to get the movement direction, "ud" will be 1, 0 or -1 depending on the keys, the same for "lr".

Have fun!

#11 Rybags ONLINE  

Rybags

    Gridrunner

  • 16,029 posts
  • Location:Australia

Posted Wed Feb 20, 2019 4:35 PM

For a 10-liner you'd obviously exclude other keys.  In such case it might be just easier to use the K: handler as the coding requirements are probably the least.

 

Initially you need OPEN #1,4,0,"K"

Optionally clear any buffered key with POKE 764,255.

Wait for keypress with GET #1,A

The problem with this method - your program pauses during the wait for key, and some key combinations don't register.  And you get a keyclick.



#12 pirx OFFLINE  

pirx

    Moonsweeper

  • 450 posts
  • Location:Poland

Posted Thu Feb 21, 2019 3:31 AM

 k=peek(764):poke764,9:ud=(k=5)-(k=13):lr=(k=0)-(k=1)

 

dmsc is a god of atari basic, obviously :]



#13 dr.geek OFFLINE  

dr.geek

    Combat Commando

  • 3 posts

Posted Thu Feb 28, 2019 2:07 PM

Thanks! The problem is that I am doing this for a 10-liner... In other BASIC dialects I need 5 characters "get a$" or 10 characters a$=inkeys$.
I was looking for a short solution and I do not need console kets and shift. I need to detect I J K L S'PACE.

'Quick and Dirty' solution that I like to use:-

 

k=peek(754)*(peek(753)=3)

 

the only drawback is that the 'L' key also returns a zero value - but this can be worked around if you don't mind adding some extra code - or just don't use the 'L' key



#14 Stephen OFFLINE  

Stephen

    Quadrunner

  • 7,544 posts
  • A8 Gear Head
  • Location:No longer in Crakron, Ohio

Posted Thu Feb 28, 2019 5:44 PM

I love these neat tricks!



#15 dmsc OFFLINE  

dmsc

    Moonsweeper

  • 499 posts
  • Location:Viņa del Mar, Chile

Posted Thu Feb 28, 2019 6:56 PM

Hi!
 

'Quick and Dirty' solution that I like to use:-
 
k=peek(754)*(peek(753)=3)
 
the only drawback is that the 'L' key also returns a zero value - but this can be worked around if you don't mind adding some extra code - or just don't use the 'L' key

Good trick!

You could do:
k=peek(754)+256*peek(753)
and compare with 768 (L), 773 (K), 769 (J), etc.

Or in TurboBasicXL:
k=dpeek(753)
and compare with 3 (L), 1283 (K), 259 (J), etc.

#16 dr.geek OFFLINE  

dr.geek

    Combat Commando

  • 3 posts

Posted Fri Mar 1, 2019 9:17 PM

&amp;nbsp;

Hi!
 
Good trick!

You could do:

k=peek(754)+256*peek(753)
and compare with 768 (L), 773 (K), 769 (J), etc.

Or in TurboBasicXL:
k=dpeek(753)
and compare with 3 (L), 1283 (K), 259 (J), etc.
&amp;nbsp;


or

k=(peek(754)+1)*(peek(753)=3)

just adds 1 so L is now 1 but null is still 0 (all other keypresses are also +1)

Edited by dr.geek, Fri Mar 1, 2019 9:21 PM.


#17 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Tue Mar 19, 2019 2:36 AM

What makes these are "peek"-methods superior to my current bad solution:
S=PEEK(764):POKE 764,255:IFS<>255THEN...

 

My current solution ramdomly fails to detect some key-resses.

In other BASIC dialects the solution is provided by GET or INKEY$.

 

I guess that all these methods suffer from the same issue: they read the unbuffered keyboard status and so if, by bad luck, the key was releases just before the peek, no key-press is detected.

So I fear that all these solutions are bad...

Am I wrong?
Is peek(754)+256*peek(753) better? Why?
How do I detect no key pressed with peek(754)+256*peek(753)?

 



#18 Rybags ONLINE  

Rybags

    Gridrunner

  • 16,029 posts
  • Location:Australia

Posted Tue Mar 19, 2019 3:46 AM

The problem is POKEing 764,255 after reading it - you should only do that once a keypress has been processed and you're ready to deal with the next one.

Otherwise you just run the chance of missing keypresses.  The OS only stores the keycode in there when the key has been pressed, then again if autorepeat starts for each repeat sequence.



#19 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Tue Mar 19, 2019 3:56 AM

@Rybags, what do you suggest then?
I do not want to have auto-repeat and I do not want to miss key-presses.
I want to detect the last key pressed just once without missing it and without detecting it twice unless it is released and re-pressed.


Edited by Fabrizio Caruso, Tue Mar 19, 2019 3:56 AM.


#20 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Tue Mar 19, 2019 4:26 AM

@Rybags, I do S=PEEK(764):POKE 764,255
what do you mean by processing? I store the value of PEEK(764) into S *before* I set it back to 255. 

 


Edited by Fabrizio Caruso, Tue Mar 19, 2019 4:26 AM.


#21 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Tue Mar 19, 2019 8:07 AM

I wonder whether I am fighting against an impossible problem on the Atari 8-bit:
Is it possible to read the keyboard WITHOUT auto-repeat (just one key for each key-down) and YET in a BUFFERED way (no key-press lost)?

This is possible on most other 8 bit computers (e.g., the Commodore 8-bit computers can)


Edited by Fabrizio Caruso, Tue Mar 19, 2019 8:07 AM.


#22 antrykot OFFLINE  

antrykot

    Space Invader

  • 35 posts

Posted Tue Mar 19, 2019 10:01 AM

10 POKE 729,0
20 K=PEEK(764):IF K<>255 THEN POKE 764,255:? K
30 GOTO 20



#23 Fabrizio Caruso OFFLINE  

Fabrizio Caruso

    Chopper Commander

  • Topic Starter
  • 105 posts

Posted Tue Mar 19, 2019 12:19 PM

@antrykot THANKS! Your solution seems to be the perfect one for me!
THANKS A LOT!
I also works with 9 instead of 255 (to save a few characters)
 







Also tagged with one or more of these keywords: basic

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users