Introduction To The 6522 VIA (Versatile Interface Adapter):

The 6522 VIA (Versatile Interface Adapter) was one of the finest I/O chips
ever developed. It had both a simple, elegant pin configuration/hardware
implementation and excellent functionality, with two 8-bit I/O buses that
could be easily controlled through a regular 8-bit CPU's data bus. Even
today, the 6522 is a perfectly usable I/O controller.

The 6522, like almost any standard IC, has its pins numbered from top-left to
lower-left, and then from bottom-right to top-right. In other words, the
top-leftmost pin is pin 1, the bottom-left pin is pin 20, the bottom-right
pin is pin 21, and the top-right pin is pin 40. (This is all with the chip's
orientation notch at the top.) The 6522's pinout is as follows:

1: Vss (Ground)
2: PA0
3: PA1
4: PA2
5: PA3
6: PA4
7: PA5
8: PA6
9: PA7
10: PB0
11: PB1
12: PB2
13: PB3
14: PB4
15: PB5
16: PB6
17: PB7
18: CB1 (Control for Port B)
19: CB2 (Control for Port B)
20: Vcc (+5V)
21: IRQ (Active-low; Output to the CPU, not an input to the VIA)
22: R/W (High = read, low = write)
23: CS2 (Chip Select 1; Active-low)
24: CS1 (Chip Select 2; Active-high)
25: CLK2 (Enable)
26: D7
27: D6
28: D5
29: D4
30: D3
31: D2
32: D1
33: D0
34: RES (Reset; active-low)
35: RS3 (Register Select 3)
36: RS2 (Register Select 2)
37: RS1 (Register Select 1)
38: RS0 (Register Select 0)
39: CA2 (Control for Port A)
40: CA1 (Control for Port A)

Vss is ground, and Vcc is +5 volts, as usual.

CLK2 is normally tied to the 6502 CPU's CLK2 output. This signal will
actually trigger the 6522, and make it perform whatever read/write operation
is selected. Although it is normally pulsed at a constant frequency by the
CPU, you can actually trigger CLK2 by hand, using a push-button switch, if
you are operating the 6522 manually. This may be thought of as the "Enable"
signal, and it is usually called the "Enable" pin in this document, since
that's a little more appropriate a term for it when you're working with the
6522 alone (as opposed to when you're using it in conjunction with the 6502,
where it makes a little more sense since CLK2 or PHI2 refers to a clock
output pin on the 6502).

The D pins are the data bus.

The two CS (Chip Select) pins enable the chip. For the chip to be enabled,
CS1 must be high and CS2 must be low. If these two conditions are not met,
the chip will not respond. These pins are normally tied to the computer's
address bus.

The RS (Register Select) pins are also normally tied to the address bus, so
the computer can select which register in the 6522 to access. Together with
the R/W pin, the CPU can read to and write from the 6522's internal registers
as follows:

To read a register on the 6522:

Ensure that the two CS pins are active, R/W is high (for read), and that the
RS pins are set to the register you want to read. Then pulse the CLK2 pin,
and the 6522 will place the contents of the selected register onto the data
bus.

To write to a register on the 6522:

Ensure that the two CS pins are active, R/W is low (for write), and that the
RS pins are set to the register you want to write to. Place the value you
want to store in this register on the data bus, and pulse the CLK2 pin. The
6522 will store the contents of the data bus in the selected register.

Note that the Output Registers (ORs) and Input Registers (IRs) behave
slightly differently, because they actually depend on what is on the I/O bus
right now, or what has been sent to it; They are not normal storage registers
like the other registers on the 6522.

The PA and PB pins form the two actual I/O buses.

The CA and CB pins, which are the "control" pins for the two I/O buses, are
mostly for interrupts and handshaking; However, CA1 and CB1 serve another
important function as they control "input latching" for the two I/O buses.

Input latching is basically a way to store something sent to the VIA without
having to read the I/O bus immediately. When you latch one of the input
registers (IRs), it stores whatever is currently on its I/O bus, and it will
store that value so the CPU can read it later. If input latching is turned
off, then the IR will be "transparent", matching whatever is currently on
the I/O bus pins. The state of the IR will change without even having to
cycle the VIA's Enable pin. On the other hand, if input latching is turned
on, then the IR will contain whatever was on the I/O bus pins at the time of
the last latch.

If input latching is turned on, when CA1 goes active, IRA will latch whatever
is currently on the PA pins. Similarly, when CB1 goes active, IRB will latch
whatever is currently on the PB pins. (Notice that we are careful to say
"active", not "high" or "low", because CA1 and CB1 can be set to either
active-high or active-low.) In the latching context, CA1 or CB1 are usually
connected to the peripheral(s), so the peripheral can send the VIA a "data is
currently being sent" signal, so the VIA can then store the current data from
the peripheral and pass it on to the CPU when the CPU reads it. CA1 is set to
active-high or active-low through the last bit (bit 0) of the PCR, or
Peripheral Control Register (at Register Select address C hex, 12 decimal, or
1100 binary). If that bit is 0, CA1 is active-low; If that bit is 1, CA1 is
active-high. CB1 is set to active-high or active-low through the fourth bit
(bit 4) of the PCR. If that bit is 0, CB1 is active-low; If that bit is 1,
CB1 is active-high.

Input latching is enabled/disabled via the ACR, or Auxiliary Control
Register. The ACR is at address B (1011) of the Register Select pins. The
last two bits of this register control latching; The second-last bit is for
port B, and the last bit is for port A. If the corresponding bit in the ACR
is on (1), then latching for that port is enabled. If the corresponding bit
in the ACR is off (0), then latching for that port is disabled.

Behaviour for reading the IRs is as follows:

If you read a pin on IRA and input latching is disabled for port A, then you
will simply read the current state of the corresponding PA pin, regardless of
whether that pin is set to be an input or an output.

If you read a pin on IRA and input latching is enabled for port A, then you
will read the actual IRA, which is the last value that was latched into IRA.

If you read a pin on IRB and the pin is set to be an input (with latching
disabled), then you will read the current state of the corresponding PB pin.

If you read a pin on IRB and the pin is set to be an input (with latching
enabled), then you will read the actual IRB.

If you read a pin on IRB and the pin is set to be an output, then you will
actually read ORB, which contains the last value that was written to port B.

Writing to a pin which is set to be an input will change the OR for that pin,
but the state of the pin itself will not change as long as the DDR dictates
that it is an input.

Note that there is no such thing as "output latching" on the 6522; Writing to
ORA or ORB will always simply set the OR, and the OR will then retain that
value until it is written to again. The ORs are also never transparent;
Whereas an input bus which has input latching turned off can change with its
input without the Enable pin even being cycled, outputting to an OR will not
take effect until the Enable pin has made a transition to low or high.

The direction of the I/O buses can be set (to be either input or output) via
the Data Direction Register. (DDRA and DDRB are the Data Direction Registers
for I/O bus A and I/O Bus B.) The actual output can be sent by the Output
Register (ORA or ORB). The two I/O buses also have Input Registers (IRA and
IRB). ORA and IRA use the same Register Select codes, as do ORB and IRB.
Whether the OR or the IR is used depends entirely upon the state of the DDR.
When an I/O bus pin is set to be an output (via the DDR), you write to it
through the OR. (Writing to a pin which is set to be an input does nothing.)
When an I/O bus pin is set to be an input, you read from it through the IR.
However, since the OR and the IR use the same address, their separate
existence is transparent. ORA and IRA are 0001 (RS0 high, all others low),
ORB and IRB are 0000 (all RS pins low). DDRA is 0011 and DDRB is 0010.

To output to a peripheral from the CPU through the I/O bus:

1. Set the RS pins to 0010 or 0011 (for DDRA or DDRB).
2. Set the data bus to 11111111. (All 1s, making all the I/O bus pins
  outputs.)
3. Enable both CSes.
4. Make sure R/W is low.
5. Pulse CLK2.
(DDRA or DDRB is now set to make all I/O pins on that bus act as outputs.)
6. Set the RS pins to 0000 or 0001 (for ORA or ORB).
7. Set the data bus to whatever you want to output on the I/O bus.
8. Enable both CSes.
9. Make sure R/W is low.
10. Pulse CLK2.

To input from a peripheral to the CPU through the I/O bus:

1. Set the RS pins to 0010 or 0011 (for DDRA or DDRB).
2. Set the data bus to 00000000. (All 0s, making all the I/O bus pins
  inputs.)
3. Enable both CSes.
4. Make sure R/W is low.
5. Pulse CLK2.
(DDRA or DDRB is now set to make all I/O pins on that bus act as inputs.)
6. Set the RS pins to 0000 or 0001 (for IRA or IRB).
7. Enable both CSes.
8. Make sure R/W is high.
9. Pulse CLK2.
(Data from the selected I/O bus should now appear on the system data bus.)

Quick tutorial for the 6522:

Begin by hooking up power to Vcc and Vss. Enable both Chip Select pins (make
CS1 high and CS2 low).

Set RS to 0011 (for DDRA). (That is, RS3 and RS2 should be low, RS1 and RS0
should be high.) Set R/W high (for read). Keep the Enable pin low for now, to
keep the chip from doing anything.

Pulse Reset low for a moment to reset the chip, then keep it high. Now set
the Enable pin high, and check one of the data bus pins. Note its state; If
it is low (0), this means that the corresponding pin on I/O bus A is set to
be an input, while a high (1) indicates that that pin is set to be an output.

Set Enable low, then put R/W low (for write). Attach the data bus pin you
checked to either high or low, the opposite of whatever it was before. If it
was high, connect it to ground; If it was low, connect it to Vcc. Now pulse
the Enable pin momentarily, then let it go low again. Doing this should
change the state of the corresponding bit in DDRA.

To check this, set R/W high again (for read), and put Enable high. Check the
data bus pin again; It should now have changed. This is how to read and write
the state of the DDRs. DDRB is changed in exactly the same way, except that
you set the RS pins to 0010.

Put Enable low. Using DDRA, make any pin on I/O bus A be an output. (That is,
set its bit to 1 (on) in DDRA.) Now set RS to 0001 (which will select ORA).
Also set R/W to low (for write). Put Enable high, and check the status of the
corresponding pin on I/O bus A. You might want to put an LED on it so you can
see its state. Now attach a wire to the data bus pin that corresponds to that
I/O pin, and put it on the opposite of where the I/O pin is now; If the I/O
pin is high, put the data bus pin low, and if the I/O pin is low, put the
data bus pin high. Drop Enable and raise it again; The I/O pin should change
state to match whatever you are sending it through the data bus. This is how
you output to a peripheral through the 6522. Sending to I/O port B works
exactly the same way, except that you set RS to 0000 for ORB.

Put Enable low again. Set RS to 1011, which will select the ACR, which is
where you control latching for the two I/O buses. Ensure that D0 is kept low,
since that is the pin corresponding to the last bit in the ACR, which is the
bit for latching of data bus A, and we want to turn off latching for port A.
Put R/W low (for write) and pulse Enable. Latching should now be disabled for
port A.

Using DDRA, make a pin on I/O bus A be an input. (That is, set its bit to 0
(off) in DDRA.) Now set RS to 0001 (which will select IRA). Set R/W high (for
read). Put Enable high, and watch the status of the data bus pin that
corresponds to the I/O bus pin you are using. Again, you might want to attach
an LED, only this time it goes to the data bus pin. Now attach a wire to the
I/O bus pin, and watch what happens to the data bus pin when you touch the
wire to Vcc and Vss; The data bus pin should change to reflect whatever is
being sent to it through the I/O bus. This is how you input from a peripheral
through the 6522. Reading from I/O port B works exactly the same way, except,
of course, that you set RS to 0000 for IRB.

    Source: geocities.com/siliconvalley/2072

               ( geocities.com/siliconvalley)