$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.
Just imagine getting parallel input from separate rows or columns or diagonal movement from awsd controls!
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