The matrix is indexed by Rows and Columns
At each matrix intersection (at a specific row and column) a key resides.
Both Row and Column are accessed through the memory mapped Versatile Interface Adapter
or VIA for short.
The row is simply set by writing the row number into the lower 3 bits of VIA Port B at
location $0300.
The Column is less accessable because it is the IO port(AY Register $0E) on the
AY-3-8912 Sound chip.
The column register is also 8 bits wide, and to set Column 5 requires one to Clear
(not set) Bit 5 whilst setting all other bits (It's the way the hardware works!).
To work out how to write to the column Register is to work out how to write to
an AY Register.
The AY has four commands, physically passed by 2 VIA control lines, known as CA2 and CB2.
The logic on these lines dictate the type of information that will appear on VIA Port A.
Code: Select all
CA2 CB2 Type
0 0 Port A is not connected to AY
0 1 Port A data is taken as Data for the currently selected AY Register
1 0 Port A is deposited with Data from the currently selected AY Register
1 1 Port A data is taken as the AY Register Number which should range $00-$0E
location $030C.
The Peripheral Control Register not only controls CA2 and CB2 but also CA1 and CB1.
CA1 and CB1 are controlled by a single bit Register(in B0 and B4) whereas CA2 and CB2 are
controlled by two 3 bit registers(B1-3 for CA2 and B5-7 for CB2).
CA1 and CB1 can be ignored since the Register bit for both is always set to 1.
Both CA2 and CB2 have the same format of settings in the 3 bit registers.
The first 4 values in the 3 Bit registers (0-3) can be ignored since they treat the lines
as inputs rather than outputs.
Code: Select all
CA2 and CB2 Setting
100 Handshake output
101 Pulse Mode (Set Line momentarily high when Port B read or written to)
110 Set Line Low
111 Set Line High
And to Write the column value via_pcr should be written with 111 1 110 1 or $FD
However, the lines should be set inactive between operations to ensure Register
number doesn't get taken as Register Data and vice versa.
The Real AY also doesn't like it if CB2 is set high for too long and tends to crash
the system in some weird way. However the Euphoric does not Emulate this behaviour
and will happily run as normal regardless how long CB2 is held high.
To set both lines low, we would write 110 1 110 1 or $DD to via_pcr
After setting Column and Row on the real Oric, we need to wait a few microns for
the curcuit to "Settle". Again Euphoric behaves differently in that it will
instantaneously return the key condition.
Finally we can read the key condition in Bit 4 (Value of Port B.
Lets try this in code
Code: Select all
ReadFunctKey
;Store AY Register $0E to Port A
lda #$0E
sta via_porta
;Set Lines to Register data
lda #%11111111 ;CB2 CA2 = 11
sta via_pcr
;Set lines inactive
lda #%11011101 ;CB2 CA2 = 00
sta via_pcr
;Store Column 4 to Port A
lda #%11110111
sta via_porta
;Set lines to Write Data
lda #%11111101 ;CB2 CA2 = 10
sta via_pcr
;Set Lines inactive again
lda #%11011101 ;CB2 CA2 = 00
sta via_pcr
;Store Row number 5 to Port B
lda #5
sta via_portb
;Wait a 4 cycles for the curcuit to settle
nop
nop
;Read back the key condition bit
lda via_portb
and #8
rts
The routine will return 8 in the accumulator if the function key was pressed and 0 if
it wasn't.