How a hardware flaw gave the Commodore 64 a screen-flickering typing speed limit
The Commodore 64 sold millions of units, but its MOS Technology VIC-II graphics chip had a notorious design quirk. Whenever the chip drew text or graphics, it stole memory bus cycles directly from the main processor for 40 to 43 clock cycles per scanline. If a programmer typed or transferred serial data too quickly while the screen displayed graphics, missed clock cycles dropped characters entirely unless the screen was blanked.
The Economics of Shared Memory
When Commodore International developed the Commodore 64 in the early 1980s, keeping retail costs low was a primary engineering requirement. Personal computers of the era often relied on expensive dual-ported random-access memory or dedicated video memory banks to allow the central processor and the display controller to access system memory simultaneously. To avoid the substantial expense of separate memory pools, Commodore engineers designed the machine around a single pool of 64 kilobytes of dynamic RAM shared directly between the MOS Technology 6510 central processing unit and the MOS Technology 6567 or 6569 Video Interface Chip II, commonly known as the VIC-II.
The system coordinated memory access through an interleaved two-phase clock running at approximately one megahertz. Under normal conditions, the clock cycle was split cleanly in half. During the first phase of the cycle, when the system clock signal was low, the VIC-II accessed system memory to fetch screen data, border information, and sprite graphics. During the second phase, when the clock signal went high, the 6510 processor took control of the address and data lines to read program code and manipulate variables. This strict temporal division allowed both integrated circuits to operate concurrently without colliding, creating the illusion of transparent, non-blocking memory access while keeping component costs minimal.
The Mechanics of Bad Lines
This interleaved arrangement functioned smoothly until the VIC-II required more memory bandwidth than its standard clock phase could supply. While standard character pointers and color attributes occupied predictable slots, generating full 40-column text or bitmap graphics across the visible display area demanded rapid, burst-style memory reads. Every eighth raster scanline within the active display window, the VIC-II needed to fetch an entire row of 40 character pointers from the screen matrix to refresh its internal line buffer. The single low phase of the clock was insufficient to pull all 40 bytes in time for the raster beam to paint the cathode ray tube.
To satisfy this bandwidth demand, the VIC-II asserted hardware priority over the shared memory bus through a dedicated control line designated as Bus Available, or BA. At the start of one of these critical scanlines—known universally among Commodore programmers as 'bad lines'—the VIC-II pulled the BA line low three clock cycles before it required the bus. Upon detecting the lowered signal, the 6510 processor finished its current read or write cycle and surrendered control, effectively halting CPU execution. The VIC-II then took exclusive ownership of the bus, stealing between 40 and 43 consecutive clock cycles directly from the processor. If hardware sprites were also active on that same scanline, the chip demanded an additional two cycles per sprite, extending the processor's forced pause even further.
Bit-Banging and Timing Cascades
The regular loss of CPU cycles was inconsequential for simple calculations, but it created severe complications for timing-sensitive input and output operations. In the original design of the Commodore 64, peripheral communication across the Commodore serial IEEE-488 bus was intended to use the hardware shift registers inside the MOS Technology 6526 Complex Interface Adapter (CIA) chips. However, a silicon flaw discovered late in the development of the 6526 rendered its internal shift registers unreliable for high-speed serial transfers. Rather than delay production to spin a new silicon revision, Commodore's software engineers rewrote the operating system's KERNAL routines to drive serial communication manually through software timing loops, an approach known as bit-banging.
Bit-banging relies entirely on cycle-exact processor timing. In software-timed loops, the CPU toggles lines and samples voltage levels at strict, microsecond-level intervals calculated directly from the instruction cycle counts of the 6510. When the VIC-II asserted the BA line to service a bad line, it froze the processor mid-execution, interrupting the software timing loop without the CPU's awareness. This unpredictable freeze stretched the duration of clock pulses and delayed input sampling. The receiving or transmitting peripheral fell completely out of synchronization, resulting in framing errors, corrupted bytes, or characters dropped entirely from serial transfers and keyboard scanning buffers.
The Screen Blanking Workaround
Because the serial bus lacked modern hardware flow control to pause external peripherals while the processor was stalled, software developers had to devise workarounds within the constraints of the VIC-II's register architecture. The most direct solution involved the VIC-II's primary control register, located at memory address $D011. Bit 4 of this register controlled the display state: setting the bit enabled normal raster generation, while clearing the bit blanked the screen completely, replacing the graphic display with a solid border color.
When the display was blanked via register $D011, the VIC-II stopped generating bad lines entirely. Because it no longer had to fetch character matrix data or bitmap graphics for the raster beam, the chip stopped asserting the BA line, returning 100 percent of the memory bus cycles to the 6510 processor. Commercial disk utilities, software fastloaders, and data transmission programs routinely cleared this bit before initiating high-speed transfers. Users accustomed to commercial Commodore 64 software became familiar with the distinct visual side effect: the monitor would flash black or flicker into a blank border color during fast disk access, ensuring the processor ran without interruption until the data transfer completed.
Architectural Nuance and Programming Feats
While bad lines initially presented a design hurdle, assembly language programmers and demoscene coders eventually exploited their deterministic nature to achieve unintended graphic capabilities. Because bad lines occurred predictably based on the vertical position of the raster counter and the scroll register settings, clever software could manipulate register $D011 mid-frame to alter when and where bad lines triggered. By adjusting the vertical smooth-scrolling bits before the raster beam reached the trigger line, programmers could trick the VIC-II into skipping bad lines altogether or forcing them to occur on non-standard scanlines, a technique that eliminated borders and allowed graphics to be displayed in the overscan area.
The bus contention between the VIC-II and the 6510 remains one of the defining case studies of early microcomputer engineering compromises. By prioritizing cost efficiency and silicon simplicity over independent memory architectures, MOS Technology delivered an affordable, capable graphics processor that made the Commodore 64 accessible to a mass audience. The resulting cycle-stealing quirks forced programmers to master low-level timing at the hardware level, transforming an unintended bus bottleneck into one of the most thoroughly analyzed subsystems in personal computing history.
Key takeaways
•The Commodore 64 avoided costly multi-port RAM by sharing a single pool of system memory between the 6510 CPU and the VIC-II graphics chip using interleaved clock phases.
•On every eighth scanline of visible graphics—known as 'bad lines'—the VIC-II asserted the Bus Available line to halt the CPU and steal 40 to 43 cycles for character fetches.
•Because a silicon bug forced the system to rely on software bit-banging for serial I/O, the unpredictable CPU stalls caused timing failures and dropped data during fast transfers.
•Programmers overcame the cycle-stealing problem by blanking the screen via register $D011, disabling bad lines and returning full processing power to the CPU during critical operations.