MOS Technology 6522
The MOS Technology 6522, commonly known as the Versatile Interface Adapter (VIA), is an 8-bit integrated circuit developed for input/output interfacing in microcomputer systems compatible with the 6502 microprocessor family.[1] It provides two bidirectional 8-bit parallel ports (Port A and Port B), each with programmable data direction registers and associated handshake control lines for synchronized data transfers.[1] Additional features include two independent 16-bit interval timers (one configurable as an event counter), an 8-bit parallel-to-serial or serial-to-parallel shift register for asynchronous serial I/O, and an interrupt generation system to signal the processor of peripheral events.[1] Operating on a single +5V supply with TTL-compatible I/O pins, the chip was fabricated using N-channel depletion-load technology and introduced in preliminary form in November 1977.[1] The 6522 was a key support component in the MOS Technology 65xx ecosystem, enhancing the basic parallel interface adapter (6520 PIA) with timing and serial capabilities to enable more complex peripheral control in resource-constrained systems.[2] It found widespread adoption in early personal computers and embedded applications during the late 1970s and 1980s, including the Commodore KIM-1 single-board computer for user I/O ports,[3] the Commodore PET series for cassette and user port interfacing,[4] and the VIC-20 for general peripheral management.[5] In disk drive systems, such as the Commodore 1541, it handled serial bus communications and timing, though early implementations sometimes required software workarounds due to hardware limitations like shift register bugs.[6] The chip's versatility also extended to non-Commodore platforms, supporting joystick, printer, and modem interfaces in 6502-based designs from manufacturers like Rockwell International, which produced compatible versions.[2] Over time, the 6522 influenced subsequent I/O chips, such as the MOS 6526 Complex Interface Adapter (CIA) used in the Commodore 64, which addressed some of its shortcomings while maintaining compatibility.[6] Modern reproductions and CMOS variants, like the Western Design Center W65C22, continue to be available for retro computing and hobbyist projects, preserving its role in emulating classic 8-bit systems.[2]History and Development
Introduction
The 6522 played a pivotal role in 1970s and 1980s computing by providing essential I/O functionality in numerous 6502-based systems, including the Commodore VIC-20 and PET, Apple III, BBC Micro, Vectrex video game console, and the digital dashboard of the 1984–1989 Chevrolet Corvette.[7][8] It was second-sourced by manufacturers including Rockwell (as the R6522) and Synertek to meet demand in microprocessor-based designs.[2]Design Origins and Release
The MOS Technology 6522 Versatile Interface Adapter (VIA) was developed in the mid-1970s as an enhancement to the company's 6520 Peripheral Interface Adapter (PIA), which provided basic parallel I/O capabilities similar to the Motorola MC6820 but optimized for the MOS 6502 microprocessor ecosystem.[1] The 6522 extended this foundation by incorporating two independent 16-bit interval timers and an 8-bit parallel-to-serial shift register, enabling more versatile peripheral control, timing functions, and serial data handling in cost-sensitive microcomputer designs.[1] MOS Technology was acquired by Commodore International in 1976, during the chip's development phase. Building on the company's growing expertise in NMOS fabrication from the 6502 CPU (introduced in 1975) and the 6520 PIA, the 6522 was engineered to support comprehensive interfacing needs for emerging home and hobbyist systems, such as keyboard input, printer control, and basic serial communications, all within a single chip to minimize system complexity and cost.[1] A preliminary datasheet for the device was issued in November 1977, marking its initial technical disclosure.[1] The chip entered full production in 1978, manufactured using an N-channel depletion-load NMOS process on a single +5V supply, housed in a 40-pin dual in-line package (DIP) for TTL compatibility and ease of integration.[9] To ensure broader availability amid MOS Technology's rapid expansion alongside the 6502 family, the design was second-sourced by Rockwell International as the R6522[10] and by Synertek as the SY6522.[9] Its low unit cost in volume, along with inclusion in MOS reference designs, drove early adoption in systems like the Commodore PET, facilitating the growth of affordable 6502-based microcomputers.[11]Architecture and Interfaces
Register Map
The MOS Technology 6522 Versatile Interface Adapter (VIA) organizes its internal functions into 16 consecutive 8-bit memory-mapped registers, selected using a 4-bit address decoder driven by lines RS0–RS3. These registers are accessed relative to a base address determined by the chip select inputs CS1 (active high) and CS2 (active low), with the device responding when CS1 is high, CS2 is low, and the R/¯W line specifies the operation, all synchronized to the falling edge of the φ2 clock.[12] Register access follows specific protocols: writes latch data from the system data bus into the selected register on the falling edge of φ2, while reads transfer the register contents to the data bus valid on the rising edge of φ2; for example, writing to data direction registers configures port I/O immediately, and reading the interrupt flag register does not clear flags unless explicitly written to. Certain registers exhibit dual functions, such as timer counters that preload from latches on access, and interrupt flags that clear only when a '1' is written to the corresponding bit. The base address allows integration into systems like the 6502 microprocessor bus, typically occupying 16 bytes in memory space. Note that the final production 6522 register map differs from the November 1977 preliminary datasheet, which had an alternate arrangement of timer and shift registers.[12] The following table summarizes the register map, with hexadecimal offsets from the base address:| Offset | Register Name | Function Description |
|---|---|---|
| $00 | Port B Data (ORB/IRB) | 8-bit bidirectional I/O for Port B; write sets output levels, read returns input or latched output. |
| $01 | Port A Data (ORA/IRA) | 8-bit bidirectional I/O for Port A; similar to Port B, with handshake integration via CA1/CA2. |
| $02 | Port B Data Direction (DDRB) | Write-only; configures each Port B bit as input (0) or output (1). |
| $03 | Port A Data Direction (DDRA) | Write-only; configures each Port A bit as input (0) or output (1). |
| $04 | Timer 1 Counter Low (T1C-L) | Read returns low byte of Timer 1 counter (clears interrupt flag); write loads low latch. |
| $05 | Timer 1 Counter High (T1C-H) | Read/write accesses high byte of Timer 1 counter; writing starts countdown and clears flag. |
| $06 | Timer 1 Latch Low (T1L-L) | Read/write low byte of Timer 1 preload latch. |
| $07 | Timer 1 Latch High (T1L-H) | Read/write high byte of Timer 1 preload latch; writing to high initiates transfer to counter. |
| $08 | Timer 2 Counter Low (T2C-L) | Read returns low byte of Timer 2 (clears flag); write loads low latch. |
| $09 | Timer 2 Counter High (T2C-H) | Read/write high byte of Timer 2; writing starts operation and clears flag. |
| $0A | Shift Register (SR) | 8-bit serial/parallel data buffer; read/write transfers data for shifting. |
| $0B | Auxiliary Control Register (ACR) | Configures operational modes for timers and shift register. |
| $0C | Peripheral Control Register (PCR) | Sets input/output modes for peripheral control lines CA1/CA2/CB1/CB2. |
| $0D | Interrupt Flag Register (IFR) | Read shows pending interrupts; write '1' to bits to clear specific flags. |
| $0E | Interrupt Enable Register (IER) | Enables/disables interrupt sources; bit 7 sets/clears all enables. |
| $0F | Port A Data No Handshake (ORA/IRA no CA2) | Accesses Port A without affecting CA2 control lines. |
Pin Configuration
The MOS Technology 6522 is packaged in a 40-pin dual in-line (DIP) configuration, facilitating integration into microprocessor-based systems such as those using the 6502 family. Power connections include Vcc (+5 V supply) at pin 40 and Vss (GND) at pin 28, with the device designed for single +5 V operation and TTL-compatible logic levels across all inputs and outputs. The phase 2 clock input (φ2), essential for synchronizing internal operations, is located at pin 29. Address inputs for selecting internal registers (RS0 to RS3) occupy pins 12 through 15, enabling access to the chip's 16-byte register space via the host processor's address bus.[12] Key peripheral signal groups are grouped logically on the package. Port A consists of bidirectional I/O lines PA7 through PA0 at pins 1 to 8, respectively, while Port B lines are at pins 30 (PB0), 31 (PB1), 32 (PB2), 33 (PB3), 35 (PB4), 37 (PB5), 38 (PB6), 39 (PB7). Handshaking and control signals include CA1 and CA2 for Port A at pins 9 and 10, and CB1 and CB2 for Port B at pins 36 and 34; these lines support interrupt inputs, handshake outputs, and serial data/clock functions for the integrated shift register. The interrupt request output (IRQ) is provided at pin 18 as an open-drain NMOS configuration, requiring an external pull-up resistor for wired-OR operation in multi-device systems.[12] The bus interface signals ensure compatibility with the 6502's memory-mapped I/O architecture. The active-low reset input (RES) is at pin 27, the read/write control (R/W, high for read) at pin 11, and chip select inputs CS1 (active high) at pin 17 and CS2 (active low) at pin 16, allowing flexible decoding for system integration. The bidirectional data bus (D0 to D7) connects to pins 19–26. Electrical characteristics specify TTL-compatible I/O levels, with ports capable of sourcing 1 mA and sinking 1.6 mA to support typical logic interfacing.[12] Timing considerations are critical for reliable operation relative to the φ2 clock edge. For instance, address setup time requires a minimum of 180 ns before the positive φ2 transition, with hold time of 0 ns after, ensuring stable register access during 1 MHz system clocks as specified in documentation. These parameters derive from the NMOS implementation's propagation delays.[1]| Signal Group | Pins | Description |
|---|---|---|
| Power | 40 (Vcc), 28 (Vss) | +5 V supply and ground; TTL levels |
| Clock/Address | 29 (φ2), 12–15 (RS0–RS3) | System clock and register select |
| Port A | 1–8 (PA7–PA0) | Bidirectional I/O; 1 mA source, 1.6 mA sink |
| Port B | 30–33,35,37–39 (PB0–PB7) | Bidirectional I/O; same capabilities as Port A |
| Handshake Lines | 34 (CB2), 36 (CB1), 9 (CA1), 10 (CA2) | Control/interrupt/serial; TTL compatible |
| Bus Control | 27 (RES), 16 (CS2), 17 (CS1), 11 (R/W) | Reset and access controls |
| Data Bus | 19–26 (D0–D7) | Bidirectional 8-bit bus |
| Interrupt | 18 (IRQ) | Open-drain output |
Input/Output Ports
Port A and Port B
The MOS Technology 6522 Versatile Interface Adapter (VIA) incorporates two independent 8-bit bidirectional parallel input/output ports, designated Port A (PA0–PA7) and Port B (PB0–PB7), providing 16 general-purpose I/O lines in total.[1] Each port operates via a dedicated output register (ORA for Port A, ORB for Port B) and input register (IRA for Port A, IRB for Port B), allowing software to read or write data across the pins.[1] Directionality is configured on a per-bit basis using the Data Direction Register A (DDRA) for Port A and Data Direction Register B (DDRB) for Port B, where a logic '1' sets the corresponding pin as an output driven by the output register, and a logic '0' configures it as a high-impedance input that reflects the external pin state when read.[1] Data transfer occurs through direct CPU access to the data registers: writing to ORA or ORB asserts TTL-compatible output levels (high ≥2.4 V, low ≤0.4 V) on configured output pins, while reading from IRA or IRB captures the current input levels or latched values.[1] Port inputs present one standard TTL load, and outputs drive one TTL load, with ports sourcing 1 mA at VOH = 2.4 V and sinking 1.6 mA at VOL = 0.4 V. PB6 and PB7 exhibit standard drive characteristics except in specific timer modes where their functionality overrides normal I/O (e.g., PB6 as pulse counter input, PB7 as timer output).[9] Specifications here refer to the original NMOS version; CMOS variants like the W65C22 offer improved drive and speed characteristics (see Variants section). Optional input latching ensures stable data capture during asynchronous events, enabled separately for each port via the Auxiliary Control Register (ACR). Setting ACR bit 0 activates latching for Port A, storing the PA pin states into IRA upon an active edge transition on the CA1 control line, holding the value until the next transition or processor read.[13] Similarly, ACR bit 1 enables latching for Port B, capturing PB states into IRB on a CB1 transition.[13] This mechanism supports reliable peripheral interfacing without requiring continuous polling, particularly in noisy environments or with slow external devices. In practice, the ports serve versatile general-purpose I/O roles, such as driving keyboards for key matrix scanning, controlling segment displays for user feedback, or enabling memory expansion via address decoding.[14] In Commodore PET implementations, Port B is frequently dedicated to system control functions, including IEEE-488 bus handshaking (e.g., PB0 for NDAC input, PB1 for NRFD output, PB2 for ATN output, PB6 for NRFD input, PB7 for DAV input), cassette motor and data write control (PB3 and PB4), and video enable signaling (PB5).[14] These ports integrate briefly with the dedicated handshake control lines (CA1/CA2 for Port A, CB1/CB2 for Port B) to facilitate synchronized bidirectional data transfers in peripheral protocols.[1]Handshake Control Lines
The MOS Technology 6522 Versatile Interface Adapter (VIA) features four dedicated handshake control lines—CA1 and CA2 for Port A, and CB1 and CB2 for Port B—that facilitate synchronized data transfer with peripherals by supporting input detection and output signaling modes. These lines are configured through the Peripheral Control Register (PCR) at address offset $0C, which defines their operational modes, including edge-sensitive inputs for interrupt triggering or output behaviors for handshaking. CA1 and CB1 function exclusively as inputs, detecting positive or negative edges to latch data or generate interrupts, while CA2 and CB2 offer greater flexibility as either inputs (for edge detection) or outputs (for handshake or pulse generation). This setup enables the 6522 to interface with devices requiring precise timing, such as printers or modems, by coordinating data availability and acknowledgment signals.[1] In input modes, CA1 and CB1 are programmed via PCR bit 0 (CA1) and bit 4 (CB1) to respond to negative (0) or positive (1) active edges, setting corresponding bits in the Interrupt Flag Register (IFR) at offset $0D—specifically, bit 1 for CA1 and bit 3 for CB1—upon detection, which can trigger an IRQ if enabled in the Interrupt Enable Register (IER). For CA2 and CB2 in input mode, PCR bits 3-1 (CA2) and 7-5 (CB2) select negative or positive edge detection, setting IFR bits 0 (CA2) and 2 (CB2), respectively; an additional "independent interrupt input" mode (bits 001 or 011) allows these lines to generate interrupts without latching port data. When configured as outputs, CA2 and CB2 support handshake mode (PCR 100), where they assert low upon a CPU read/write to the associated port and return high only after the input line (CA1 or CB1) detects an edge, or pulse mode (101), generating a brief low pulse on each port access. Simple output options include driving the line low (110) or high (111) continuously. These modes ensure reliable peripheral communication without software polling in many cases.[1] The handshake protocols supported by these lines implement full strobe-and-acknowledge sequences for bidirectional data flow. For Port A read operations, CA1 signals "data ready" from the peripheral (triggering a latch in Port A input register upon edge), while CA2 outputs "data taken" as a handshake pulse or level to acknowledge the MPU's readiness. Port A also supports write handshaking, with CA2 indicating "data ready" to the peripheral and CA1 receiving "data taken." For Port B, handshaking is limited to writes: CB2 outputs "data ready," and CB1 inputs "data taken," latching the output data. Timing diagrams in the datasheet illustrate these sequences, ensuring compatibility with TTL-level peripherals. Such protocols were commonly used in 1970s systems for devices like parallel printers, where the 6522's control lines manage the STROBE (output) and ACKNOWLEDGE (input) signals. The lines connect directly to Port A and B data flow by latching input data on control line edges or inhibiting port access until handshake completion.[1] The following table summarizes the PCR bit assignments for configuring the control lines:| Bits | Line | Mode Description |
|---|---|---|
| 7-5 | CB2 | 000: Input, negative edge 001: Independent interrupt input, negative edge 010: Input, positive edge 011: Independent interrupt input, positive edge 100: Handshake output 101: Pulse output 110: Output low 111: Output high |
| 4 | CB1 | 0: Negative active edge 1: Positive active edge |
| 3-1 | CA2 | 000: Input, negative edge 001: Independent interrupt input, negative edge 010: Input, positive edge 011: Independent interrupt input, positive edge 100: Handshake output 101: Pulse output 110: Output low 111: Output high |
| 0 | CA1 | 0: Negative active edge 1: Positive active edge |
Timing and Serial Functions
Timers
The MOS Technology 6522 Versatile Interface Adapter (VIA) incorporates two independent 16-bit down-counters, known as Timer 1 and Timer 2, which provide flexible timing and event counting capabilities for embedded systems based on the 6502 microprocessor family. These timers count down from a loaded value to zero, generating an interrupt flag upon underflow, and operate at the system clock (ϕ₂) frequency for timing resolution. With a typical ϕ₂ frequency of 1 MHz, the timers offer a base resolution of 1 μs, enabling precise control in applications such as delay generation and periodic interrupts.[15] Timer 1 functions as a general-purpose interval timer with multiple operating modes defined by bits 7 and 6 of the Auxiliary Control Register (ACR). In one-shot mode (ACR6=0), the timer latches the programmed value upon writing to the high-order latch and counts down to zero, producing a single interrupt and optionally a pulse output; this mode is ideal for generating fixed delays. In free-running mode (ACR6=1), the timer continuously reloads from the latches upon reaching zero, inverting the output state each cycle to create a square wave or toggle signal, which supports ongoing periodic events like real-time clock generation for second-level interrupts when loaded with an appropriate value (e.g., 1,000,000 for 1-second intervals at 1 MHz). If ACR7=1, the output appears on Port B pin 7 (PB7) as a pulse (one-shot) or square wave (free-running), overriding normal I/O control and impacting Port B functionality by dedicating PB7 to timing signals. Alternatively, with ACR7=0 and the Peripheral Control Register (PCR) configured for CA2 output, the signal routes to CA2 in pulse (one-shot) or toggle (free-running) form. The clock source for Timer 1 is always internal, derived from ϕ₂. Loading occurs by writing the low byte first to T1C-L ($04), followed by the high byte to T1C-H ($05), which transfers the latched value to the counter and initiates countdown; underflow sets Interrupt Flag Register (IFR) bit 6.[15][1] Timer 2 operates similarly as a 16-bit down-counter but with only one-shot and pulse-counting modes, controlled by ACR bit 5. In one-shot mode (ACR5=0), it behaves like Timer 1's one-shot operation, counting down from the loaded value for interval timing, such as baud rate generation in serial communications by using the output to clock external UARTs. In pulse-counting mode (ACR5=1), Timer 2 decrements on each negative edge detected at Port B pin 6 (PB6), functioning as an event counter for input capture, such as tallying external pulses from sensors or switches until reaching zero. The clock source is internal ϕ₂ in one-shot mode, or external transitions on PB6 in counting mode. Outputs route to CB2 when the PCR sets CB2 as an output, providing a pulse or level signal on underflow. Loading follows the same sequence: low byte to T2C-L ($08), then high byte to T2C-H ($09), which loads and starts the counter; underflow sets IFR bit 5. In counting mode, PB6 serves as input, potentially affecting Port B I/O availability.[15][9] Both timers operate at the ϕ₂ clock rate, allowing intervals up to approximately 65 ms at 1 MHz ϕ₂, and generate interrupts on underflow (IFR bits 6 for Timer 1 and 5 for Timer 2), which must be cleared by reading the low-order counter or writing the high-order latch. These features enable applications like precise delays in software loops, baud rate timing for asynchronous serial interfaces (e.g., 9600 baud via appropriate load values), and input capture for measuring pulse widths or frequencies without CPU intervention.[15]Shift Register
The MOS Technology 6522 includes an 8-bit shift register designed for serial-to-parallel and parallel-to-serial data conversion, enabling bidirectional serial input/output operations integrated with the device's Port B and control lines CB1 and CB2. This register is loaded in parallel from Port B upon setting bit 7 of the Auxiliary Control Register (ACR), allowing data prepared on Port B to be shifted serially out via the CB2 pin or shifted in from CB2 to fill the register. The shifting occurs on each active clock edge, supporting LSB-first for input operations and MSB-first for output operations to accommodate standard serial protocols.[1][16] The shift register's operating modes are configured via bits 4–2 of the ACR, where bit 4 determines the direction (0 for shift-in, 1 for shift-out) and bits 3–2 select the clock source. In disabled mode (ACR bits 4:2 = 000), no shifting occurs. For shift-in (ACR4=0), the modes are: T2 underflow clock (001), ϕ₂ clock (010), or external CB1 transitions (011), loading serial data from CB2 into the register. For shift-out (ACR4=1), the modes are: free-running recirculation at T2 rate (100), T2 underflow clock (101), ϕ₂ clock (110), or external CB1 clock (111), outputting data on CB2 after initial parallel load from Port B. The free-running output mode (100) recirculates the shifted data continuously after the initial 8-bit transfer.[1][9][16] Clocking for the shift register derives from three sources: the internal system ϕ₂ clock for high-speed operations, external transitions on the CB1 pin for asynchronous serial interfaces, or underflow pulses from Timer 2 for programmable rates. These sources support serial data rates up to approximately 500 kHz, limited by the ϕ₂ frequency typically around 1 MHz in 6502-based systems, enabling efficient serial communication without additional hardware. Upon completion of an 8-bit transfer in active modes, bit 1 of the Interrupt Flag Register (IFR) is set, generating an interrupt if enabled via the corresponding bit in the Interrupt Enable Register (IER), allowing the CPU to handle the transferred data.[1][9][16] In practice, the shift register facilitates UART-like serial I/O for peripherals such as printers, modems, or simple networks, where parallel data from the system is serialized for transmission or deserialized for reception, reducing the need for dedicated serial controllers in embedded 6502 designs. For example, in shift-out mode clocked by ϕ₂, an 8-bit byte loaded from Port B can be transmitted serially on CB2 at the system clock rate, with CB1 optionally used for synchronization if external clocking is selected. This versatility made the 6522 popular in early microcomputer systems for cost-effective serial expansion.[1][9]| ACR Bits (4,3,2) | Mode | Direction | Clock Source | Notes |
|---|---|---|---|---|
| 000 | Disabled | N/A | N/A | No operation; register holds last value. |
| 001 | Shift In | Input (LSB first) | Timer 2 underflow | Programmable rate via Timer 2. |
| 010 | Shift In | Input (LSB first) | ϕ₂ (system clock) | Serial data from CB2 loaded on ϕ₂ edges. |
| 011 | Shift In | Input (LSB first) | CB1 (external) | Clocked by CB1 transitions for async input. |
| 100 | Shift Out | Output (MSB first) | ϕ₂ (free-running at T2 rate) | Continuous recirculation after load from Port B. |
| 101 | Shift Out | Output (MSB first) | Timer 2 underflow | Programmable rate via Timer 2. |
| 110 | Shift Out | Output (MSB first) | ϕ₂ (system clock) | Serial output on CB2; initial load from Port B. |
| 111 | Shift Out | Output (MSB first) | CB1 (external) | Clocked by CB1 for sync output. |