Read keyboard from assembly

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
zx81user
Posts: 54
Joined: Mon Mar 25, 2013 3:14 am

Read keyboard from assembly

Post by zx81user »

What is the easiest/best way to get keyboard input in an assembly program? Is there a OS call that returns for example the key code if a key is pressed or say $ff if no key is pressed?

I need to read many keys, 0-9 and A-Z so to speak.

Michel
dr beep
Posts: 2076
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: Read keyboard from assembly

Post by dr beep »

zx81user wrote:What is the easiest/best way to get keyboard input in an assembly program? Is there a OS call that returns for example the key code if a key is pressed or say $ff if no key is pressed?

I need to read many keys, 0-9 and A-Z so to speak.

Michel

Code: Select all

waitkey    LD   HL,lastk                                        
           LD   A,255                                           
           LD   (HL),A                                          
wkey       CP   (HL)                                            
           JR   Z,wkey       ; 255 means no key pressed                                   
           LD   BC,(lastk)    ; read IN port and value                                  
           CALL #7BD ; translate IN port and value to key                                           
           RET         

This will give the value of the key 1-40 for shift to space in A-reg.
Also alternating HL and BC (as you can see)
User avatar
bobs
Posts: 325
Joined: Thu Aug 27, 2009 10:49 pm
Location: UK
Contact:

Re: Read keyboard from assembly

Post by bobs »

If you need to read more than one key at once (for diagonal movement, or running+jumping, for example) then you'll need to scan the input port ($FE) directly. I'll post up full information about that if it's required (don't have it to hand at the moment)
zx81user
Posts: 54
Joined: Mon Mar 25, 2013 3:14 am

Re: Read keyboard from assembly

Post by zx81user »

bobs wrote:If you need to read more than one key at once (for diagonal movement, or running+jumping, for example) then you'll need to scan the input port ($FE) directly. I'll post up full information about that if it's required (don't have it to hand at the moment)
Scanning the port would give me the same result as reading LAST_K address, right?
dr beep
Posts: 2076
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: Read keyboard from assembly

Post by dr beep »

zx81user wrote:
bobs wrote:If you need to read more than one key at once (for diagonal movement, or running+jumping, for example) then you'll need to scan the input port ($FE) directly. I'll post up full information about that if it's required (don't have it to hand at the moment)
Scanning the port would give me the same result as reading LAST_K address, right?
Wrong!
LASTK is only set when just 1 key is pressed. At first with the value of the in port and the returned value from the read.
When i.e. You would read cursorkeys you would have to read two ports and when up and right are pressed then the value of IN %11101111 would be xxx10011 you would also have to read IN %11110111 for key 5.
zx81user
Posts: 54
Joined: Mon Mar 25, 2013 3:14 am

Re: Read keyboard from assembly

Post by zx81user »

[quote="dr beep"This will give the value of the key 1-40 for shift to space in A-reg. Also alternating HL and BC (as you can see)[/quote]

Code: Select all

waitkey     LD   HL,lastk                                        
            LD   A,255                                           
            LD   (HL),A                                          
wkey        CP   (HL)                                            
            JR   Z,wkey       ; 255 means no key pressed                                   
            LD   BC,(lastk)    ; read IN port and value                                  
            CALL #7BD ; translate IN port and value to key                                           
            RET         
I tried this yesterday, it works but if you want a key to initiate just 1 event until it is released you need to modify it a bit:

Code: Select all

waitkey     LD   HL,lastk                                        
            LD   A,255                                           
;            LD   (HL),A                                          
wkey        CP   (HL)                                            
            JR   Z,wkey       ; 255 means no key pressed                                   
            LD   BC,(lastk)    ; read IN port and value                                  
            CALL #7BD ; translate IN port and value to key                                           

key1        CP MyKey1
            JR NZ, key2
;do something with key1
key2        CP MyKey2
            JR NZ, key3
;do something with key2
key3        etc etc

waitky2     LD   HL,lastk                                        
            LD   A,255                                           
wkey2       CP   (HL)      ;wait until key released
            JR NZ, wkey2

            RET         
User avatar
bobs
Posts: 325
Joined: Thu Aug 27, 2009 10:49 pm
Location: UK
Contact:

Re: Read keyboard from assembly

Post by bobs »

Personally, for games, I read from the appropriate input port(s) as required.

The keyboard is split into 8 sections - 4 'half rows' on each side, and each with a unique port number.
Below are those 8 rows, each beginning with the port number:

$FE - SHIFT, Z, X, C, & V
$FD - A, S, D, F, & G
$FB - Q, W, E, R, & T
$F7 - 1, 2, 3, 4, & 5
$EF - 0, 9, 8, 7, & 6
$DF - P, O, I, U, & Y
$BF - ENTER, L, K, J, & H
$7F - SPACE, FULL-STOP, M, N, & B

To read from a port is simple:

Code: Select all

LD A, <port number as above>
IN A, ($FE)
The value returned in the accumulator has a bit set for each key which ISN'T held, starting from bit 0 for the first of the five keys, up to bit 4 for the last.

For example, to check if K is held:

Code: Select all

LD A, $BF
IN A, ($FE)
BIT 2, A
JP Z, <address of routine to call if K is held>
Also, port #0 can be used to tell if any keys are held.
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

Re: Read keyboard from assembly

Post by PokeMon »

I wonder if the simply reading in a game via IN instruction doesn't result in screen flickering as the line counter should be reset by IN ($FE) and this process is not synchronized. :shock:
User avatar
revivalstudios
Posts: 53
Joined: Wed Feb 08, 2012 9:49 pm
Contact:

Re: Read keyboard from assembly

Post by revivalstudios »

btw. shouldn't this post be in another section/subforum?
http://www.revival-studios.com - Classic videogame development. ZX81 programs at: http://www.revival-studios.com
Please Follow me on twitter (@revival_studios) for the latest information about my upcoming game projects
User avatar
bobs
Posts: 325
Joined: Thu Aug 27, 2009 10:49 pm
Location: UK
Contact:

Re: Read keyboard from assembly

Post by bobs »

revivalstudios wrote:btw. shouldn't this post be in another section/subforum?
Yes, it should be moved to the Development section.
PokeMon wrote:I wonder if the simply reading in a game via IN instruction doesn't result in screen flickering as the line counter should be reset by IN ($FE) and this process is not synchronized. :shock:
I've not noticed any...?
Post Reply