MULTIPLE KEY INPUT

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
R'zo
Vic 20 Nerd
Posts: 514
Joined: Fri Jan 16, 2015 11:48 pm

MULTIPLE KEY INPUT

Post by R'zo »

I've been working on a way to get multiple simultaneous keypresses from the key board input and I found it.

$9120 and $9121 are used to scan the key board. $9120 sets which column is to be scanned. $9121 returns the rows on of the column being scanned as 1 bit per row. There are other registers that are needed to set up the keyboard scan but this routine wedges right into the scnkey routine and lets the kernal do all the dirty work. The bytes returned from the column scan are represented as 8 characters on the top left corner of the screen.

Retrieving the individual keypresses from these bytes would differ depending on use (whether or not you want every individual key, the first key from each row, the first key from each column etc.) Each key is referenced by column bit by row bit. I.e... In the demo (screen character 0 bit 7)=row 8 column 8. Computes mapping the Vic has a table representing on page 164.
Screenshot_20210912-231159.png
Just imagine getting parallel input from separate rows or columns or diagonal movement from awsd controls!
multi key.7z
(202 Bytes) Downloaded 52 times
code runs with 8k+block 5
load with "multi key",8,1
run with sys 40960

Code: Select all

;Title: VIC MULI KEY DEMO

;by: Ryan Liston

;date: september 12, 2021

;purpose: demonstrates multiple key input for the Commodore Vic-20

;Target: Commodore Vic-20 8k+block 5

;-------------------------------------------------------------------------------

;DESCRIPTION

;wedges key table pointer from scnkey

;reurns key row bytes for each key column in screen ram
;screen + 0 to 7 = column bit 7 to 0 represented in charachter by poke value

;wedge exits to original vector and all registers and altered ram is restored
;     allowing scnkey to continue as if nothing has happened (minus the loss of 
;     a few cycles) and output as normal. 

;This also allows scnkey to handle all the dirty work of seting and reseting
;     the via control registers 
;-------------------------------------------------------------------------------      
;CONSTANTS

code_start  = $a000           ;place code in block 5
key_vec     = $28f            ;vector to keytable pointer seteup roitines 
                              ;part of scnkey routine
port_b      = $9120           ;key column scan
port_a      = $9121           ;key row scan
screen      = 4096           ;screen location (used to store and show buffer 
                              ;values for demo)

*=code_start                 

;set up wedge
start       LDA   key_vec    ;load key_vec lsb    
            sta   vector     ;store at user jump vector lsb
            lda   key_vec+1  ;load key_vec msb      
            sta   vector+1   ;store at user jump vector msb
            lda   #<wedge    ;load lsb to the start address of the wedge 
            sta   key_vec    ;store at key_vec lsb   
            lda   #>wedge    ;load msb to the start address of the wedge  
            sta   key_vec+1  ;store at key_vec msb      
            rts
            
;wedge for multiple key input
wedge       pha          ;save a,x,y and port_b ($9210) to the stack
            txa
            pha
            tya
            pha
            lda   port_b       
            pha
            lda   #%11111110  ;value to set up the first column scan
                              ;can only scan 1 column at a time
                              ;bit for column being scanned = 0
                              ;all ather bits = 1
            ldx   #8          ;start loop counter
loop        tay               ;store column state in y
            sta   port_b      ;sets port_b to scan current column 
            lda   port_a      ;returns keys pressed as bits 0 to 7
                              ;of the row in the column set in port_b
            sta   screen,x    ;stores row byte as a character value in sreen
                              ;ram
            tya               ;transfer colomn state back to a for handling 
            sec               ;set the carry bit for rotation
            rol               ;rotate the off bit for to the next column
            dex               ;decrease the counter by 1
            bne   loop        ;loop if counter (x) > 8 
                              ;counts for the 8 bits of the port_b (column)
            pla               ;restore the entry values a,x,y and port_b ($9210)
            sta   port_b      ;of a,x,y and port_b ($9210)
            pla                
            tay
            pla
            tax
            pla
            jmp   (vector)    ;continue to the original vector

;user vector 
vector      byte  0,0


     
R'zo
I do not believe in obsolete...
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: MULTIPLE KEY INPUT

Post by chysn »

So... chords?!
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
R'zo
Vic 20 Nerd
Posts: 514
Joined: Fri Jan 16, 2015 11:48 pm

Re: MULTIPLE KEY INPUT

Post by R'zo »

chysn wrote: Mon Sep 13, 2021 5:30 pmSo... chords?!
I'm definitely going to try for it. Some one has claimed that phantom keys can occur when 3 or more keys are pressed. I'm going to have to look into that. I'll do some more experimenting when I get a chance. Build up the code to output more direct visual representation of the individual key presseses. With that I'll be able to see if phantom keys occur. If they are unstable they may be buffered out. If predictable they could be planned around or masked out.

I'm also hoping to be able to set up the vic as a midi control board.

Even if I can only reliably get 2 keys at a time there are still great possibilities. Hi/low note priority would only be a matter of rol or ror. I can do a devided keyboard. Half the keys for a vic keyboard and the other half for midi out, internal tracker like loop triggers or active parameter switches.

And of course more advanced controls for future games. I think I'll try to hash out an 8 directional awsd rouitine for fun.
R'zo
I do not believe in obsolete...
User avatar
AndyH
Vic 20 Afficionado
Posts: 364
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: MULTIPLE KEY INPUT

Post by AndyH »

Phantom keys...be interested to know if that is true, but I did not notice any evidence of that. I tested my own routines mostly in emulation but also on real hardware and everything appeared to work as I had expected and can detect as many simulateneous keypresses.

I've implemented my own routines in TRSE for PET, Vic, C64 and c16/plus 4 and didn't notice such behaviour on any of them.
--
AndyH
HEWCO | Vic 20 blog
User avatar
R'zo
Vic 20 Nerd
Posts: 514
Joined: Fri Jan 16, 2015 11:48 pm

Re: MULTIPLE KEY INPUT

Post by R'zo »

AndyH wrote: Tue Sep 14, 2021 2:02 am Phantom keys...be interested to know if that is true, but I did not notice any evidence of that. I tested my own routines mostly in emulation but also on real hardware and everything appeared to work as I had expected and can detect as many simulateneous keypresses.

I've implemented my own routines in TRSE for PET, Vic, C64 and c16/plus 4 and didn't notice such behaviour on any of them.
Thank you. I am still going to run some tests for other purposes, mainly as just part of building the code up. I will post if any phantom keypresses occur.
R'zo
I do not believe in obsolete...
groepaz
Vic 20 Scientist
Posts: 1188
Joined: Wed Aug 25, 2010 5:30 pm

Re: MULTIPLE KEY INPUT

Post by groepaz »

Phantom keys are definetely a problem... (it should be common knowledge too). Depending on what keys you press, there will be shortcuts in the matrix and extra keys detected, for example if you press 3 keys that are in an "L shape" in the matrix. The only way to prevent this from happening is putting extra diodes into the keyboard (which wasnt done in the vic20 and c64 to reduce cost).
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
malcontent
Vic 20 Hobbyist
Posts: 129
Joined: Sun Dec 26, 2010 1:51 pm

Re: MULTIPLE KEY INPUT

Post by malcontent »

See here for more details:

https://codebase64.org/doku.php?id=base ... kernal_way

Discusses 64, but the same principles apply for the VIC.
User avatar
Noizer
Vic 20 Devotee
Posts: 297
Joined: Tue May 15, 2018 12:00 pm
Location: Europa

Re: MULTIPLE KEY INPUT

Post by Noizer »

So this would mean that if you build a keyboard yourself, all you need to do is connect the diodes to make it work.
What kind of diodes would it have to be?

BR
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: MULTIPLE KEY INPUT

Post by Mike »

groepaz wrote:The only way to prevent this from happening is putting extra diodes into the keyboard (which wasnt done in the vic20 and c64 to reduce cost).
Noizer wrote:[... so] all you need to do is connect the diodes to make it work[?].
To decouple the matrix, each key contact needs to have a diode put in series, on the keyboard PCB. 64 diodes in total (the RESTORE key does not need one).
What kind of diodes would it have to be?
Preferably, Schottky diodes.
User avatar
R'zo
Vic 20 Nerd
Posts: 514
Joined: Fri Jan 16, 2015 11:48 pm

Re: MULTIPLE KEY INPUT

Post by R'zo »

AndyH wrote: Tue Sep 14, 2021 2:02 am Phantom keys...be interested to know if that is true, but I did not notice any evidence of that. I tested my own routines mostly in emulation but also on real hardware and everything appeared to work as I had expected and can detect as many simulateneous keypresses.

I've implemented my own routines in TRSE for PET, Vic, C64 and c16/plus 4 and didn't notice such behaviour on any of them.
Phantom keys are absolutely real. They don't appear in vice but vice only seems to accept 6 keys at a time.

This still has it's uses. A,S and W are on the same row while A and D are on the same column. These can be used together as long as you don't need to detect R or F since they can appear if W or S are pressed with A and D. Pressing R or F with A and D would produce W or S as phantoms as well.

code runs as unexpanded+block_5
load "multi key.prg",8,1
sys40960
multi key.7z
(350 Bytes) Downloaded 47 times

Code: Select all

;sTitle: VIC MULI KEY DEMO

;by: Ryan Liston

;date: september 12, 2021

;purpose: demonstrates multiple key input for the Commodore Vic-20

;Target: Commodore Vic-20 8k+

;-------------------------------------------------------------------------------

;DESCRIPTION

;wedges key table pointer from scnkey

;reurns key row bytes for each key column in screen ram
;screen + 0 to 7 = column bit 7 to 0 represented in charachter by poke value
;   (now appeaers as @ from being rotated out by routine.)
;extracts individual keypresses from buffer
;highlights each scharacter on screen when key is pressed
   
;wedge exits to original vector and all registers and altered ram is restored
;     allowing scnkey to continue as if nothing has happened (minus the loss of 
;     a few cycles) and output as normal. 

;This also allows scnkey to handle all the dirty work of seting and reseting
;     the via control registers 
;-------------------------------------------------------------------------------      

;kernal calls    
defm  chrout$
      jsr   $ffd2
      endm



;CONSTANTS

code_start  = $a000           ;place code in block 5
key_vec     = $28f            ;vector to keytable pointer seteup roitines 
k_vec_val   = $ebdc           ;key_vec initial value
            
                              ;part of scnkey routine
port_b      = $9120           ;key column scan
port_a      = $9121           ;key row scan

screen      = 7068            ;screen location 
screen_0    = screen+(1*22)   
screen_1    = screen+(2*22)
screen_2    = screen+(3*22)
screen_3    = screen+(4*22)
screen_4    = screen+(5*22)
screen_5    = screen+(6*22)
screen_6    = screen+(7*22)
screen_7    = screen+(8*22)            


color_ram   = 38400           ;color ram location
color_0    = color_ram+(1*22)   
color_1    = color_ram+(2*22)
color_2    = color_ram+(3*22)
color_3    = color_ram+(4*22)
color_4    = color_ram+(5*22)
color_5    = color_ram+(6*22)
color_6    = color_ram+(7*22)
color_7    = color_ram+(8*22)        


            
;-------------------------------------------------------------------------------

*=code_start                 

;set up wedge
start       lda   #<wedge    ;load lsb to the start address of the wedge 
            sta   key_vec    ;store at key_vec lsb   
            lda   #>wedge    ;load msb to the start address of the wedge  
            sta   key_vec+1  ;store at key_vec msb      
            
            
;-------------------------------------------------------------------------------

tester_1    LDA   #8          ;set screen color to
            sta   36879       ;to black on black
            ldx   #0          ;use loop
t1_loop     LDA   print_1,x   ;to print key matrix
            chrout$           ;to the screen
            inx
            cpx   #90         
            bne   t1_loop     
            rts               ;return to basic
                 

;print table for the keyboard matrix
print_1     byte  "{clear}{down}"
            byte  "{reverse on}{white}7h-08642{13}"
            byte  "{reverse on}{white}5u@outeq{13}"
            byte  "{reverse on}{white}3=:khfsc{13}"
            byte  "{reverse on}{white}1r.mbcz {13}"
            byte  "{reverse on}{white}d/,nvxls{13}"
            byte  "{reverse on}{white}r{59}ljgdac{13}"
            byte  "{reverse on}{white}r*piyrw {13}"
            byte  "{reverse on}{white}d{pound}+97531{13}"
            

;-------------------------------------------------------------------------------

;wedge for multiple key input
wedge       pha          ;save a,x,y and port_b ($9210) to the stack
            txa
            pha
            tya
            pha
            lda   port_b       
            pha
            lda   #%11111110  ;value to set up the first column scan
            sta   port_b      ;can only scan 1 column at a time
                              ;bit for column being scanned = 0
                              ;all ather bits = 1
            ldx   #8          ;start loop counter
loop        lda   port_a      ;returns keys pressed as bits 0 to 7
                              ;of the row in the column set in port_b
            cmp   port_a      ;check for stability
            bne   loop
            sta   screen-1,x  ;stores row byte as a character value in sreen
                              ;ram
            sec               ;set the carry bit for rotation
            rol   port_b      ;rotate the off bit for to the next column
            dex               ;decrease the counter by 1
            bne   loop        ;loop if counter (x) > 8 
                              ;counts for the 8 bits of the port_b (column)
            
prt         LDX   #0          ;start loop 
            ldy   #3          ;hold 3 in y for character color

prt2        tya               ;load a with color
            rol   screen      ;rotate row byte from buffer
            adc   #0          ;add the carry bit to color
            sta   color_0,x   ;store color to scrren posotion
                              ;to show keypress
            tya               ;repeat for every row.
            rol   screen+1
            adc   #0          
            sta   color_1,x
            
            tya
            rol   screen+2
            adc   #0          
            sta   color_2,x
            
            tya
            rol   screen+3
            adc   #0          
            sta   color_3,x
            
            tya
            rol   screen+4
            adc   #0          
            sta   color_4,x
            
            tya
            rol   screen+5
            adc   #0          
            sta   color_5,x
            
            tya
            rol   screen+6
            adc   #0          
            sta   color_6,x
            
            tya
            rol   screen+7
            adc   #0          
            sta   color_7,x
            
            inx
            cpx   #8          
            bne   prt2
;prt         LDX   #0
;            lda   screen
;prt2        rol
;            bcs   prt3
;            pha
;            lda   #1          
;            jmp   prt4        
;prt3        pha
;            lda   #0            
;prt4        sta   color_0,x   
;            pla
;            inx
 ;           cpx   #8          
 ;           bne   prt2
            

            pla               ;restore the entry values a,x,y and port_b ($9210)
            sta   port_b      ;of a,x,y and port_b ($9210)
            pla                
            tay
            pla
            tax
            pla
            jmp   k_vec_val    ;continue to the original vector

R'zo
I do not believe in obsolete...
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: MULTIPLE KEY INPUT

Post by Mike »

R'zo wrote:They don't appear in vice but vice only seems to accept 6 keys at a time.
That could be a restriction of your PC keyboard, not necessarily of VICE. The keyboard I am currently typing on also does not anymore recognize "J" when I type and hold "A", "S", "D", "F", "G", "H" in quick succession, in Notepad. More expensive "gaming" keyboards do however recognize an arbitrary number of keys.

BTW - the phantom keys should appear in VICE. ;)
groepaz
Vic 20 Scientist
Posts: 1188
Joined: Wed Aug 25, 2010 5:30 pm

Re: MULTIPLE KEY INPUT

Post by groepaz »

yes, they do appear in vice. and the limitations of the pc keyboard are also very real :)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
User avatar
Noizer
Vic 20 Devotee
Posts: 297
Joined: Tue May 15, 2018 12:00 pm
Location: Europa

Re: MULTIPLE KEY INPUT

Post by Noizer »

Mike wrote: Thu Sep 16, 2021 7:13 am
groepaz wrote:The only way to prevent this from happening is putting extra diodes into the keyboard (which wasnt done in the vic20 and c64 to reduce cost).
Noizer wrote:[... so] all you need to do is connect the diodes to make it work[?].
To decouple the matrix, each key contact needs to have a diode put in series, on the keyboard PCB. 64 diodes in total (the RESTORE key does not need one).
What kind of diodes would it have to be?
Preferably, Schottky diodes.
Good news, it works!!! I was able to create a 8x8 button Matrix where every singel button can be combined with any other. No more collision / bitclashing. I will post some pics later and the "driver" code.
Got some funny shapes like smilies etc. Primary purpose now clearer. I do imagine something like a "touch screen" for vic 20 for painting apps or some efficient sound tracker controller even for games.
Maybe FYI: ,
R'zo wrote: Sun Sep 05, 2021 10:20 pm Title: VCXX TOY KEYS
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
Post Reply