惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
C
Cisco Blogs
博客园 - 叶小钗
P
Privacy International News Feed
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
IT之家
IT之家
博客园 - 聂微东
Know Your Adversary
Know Your Adversary
Help Net Security
Help Net Security
罗磊的独立博客
I
Intezer
S
Schneier on Security
博客园_首页
C
CERT Recently Published Vulnerability Notes
雷峰网
雷峰网
Cisco Talos Blog
Cisco Talos Blog
宝玉的分享
宝玉的分享
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Webroot Blog
Webroot Blog
TaoSecurity Blog
TaoSecurity Blog
MyScale Blog
MyScale Blog
P
Privacy & Cybersecurity Law Blog
T
The Exploit Database - CXSecurity.com
PCI Perspectives
PCI Perspectives
Security Latest
Security Latest
H
Heimdal Security Blog
S
Secure Thoughts
Hacker News: Ask HN
Hacker News: Ask HN
Y
Y Combinator Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
SecWiki News
SecWiki News
The GitHub Blog
The GitHub Blog
A
Arctic Wolf
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
T
Threat Research - Cisco Blogs
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

Hacker News

Introducing Claude Opus 4.7 Qwen Studio The Future of Everything is Lies, I Guess: Where Do We Go From Here? GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis Moving a large-scale metrics pipeline from StatsD to OpenTelemetry / Prometheus GitHub - Nightmare-Eclipse/RedSun: The Red Sun vulnerability repository GitHub - SethPyle376/hiraeth: Local AWS emulator focused on fast integration testing, with SQS support, SQLite-backed state, and a debug-friendly web UI. GitHub - macOS26/Agent: Any AI, replaces Claude Code, Cursor, OpenClaw. Over 18 LLM providers (Claude, OpenAI, Gemini, Ollama, Zai, HF, Qwen) wired into a native Mac app that writes code, builds Xcode projects, bumps versions, manages git, automates Safari, use AppleScript, JS or Accessibility, extend Agent! w/ MCP Servers, run tasks from your iPhone via Messages. YouTube now lets you turn off Shorts I Made a Terminal Pager Burgers | マクドナルド公式 Commands — HackerNews CLI documentation ChatGPT for Excel PiCore - Raspberry Pi Port of Tiny Core Linux Live Nation illegally monopolized ticketing market, jury finds Google Broke Its Promise to Me. Now ICE Has My Data. Founding Engineer at Adaptional | Y Combinator CRISPR takes important step toward silencing Down syndrome’s extra chromosome GitHub - saffron-health/libretto: The AI toolkit for building reliable browser automations US v. Heppner (S.D.N.Y. 2026) no attorney-client privilege for AI chats [pdf] Unexpected €54k billing spike in 13 hours: Firebase browser key without API restrictions used for Gemini requests Retrofitting JIT Compilers into C Interpreters IPv6 – Google The Accursèd Alphabetical Clock Cybersecurity Looks Like Proof of Work Now Fragments: April 14 Cal.com Goes Closed Source: Why AI Security Is Forcing Our Decision | Cal.com - Scheduling Software for Online Bookings Laravel raised money and now injects ads directly into your agent When moving fast, talking is the first thing to break Too much Discussion of the XOR swap trick – Heather Cafe Introduction to Spherical Harmonics for Graphics Programmers The Grand Line Building a Z-Machine in the worst possible language High-Level Rust: Getting 80% of the Benefits with 20% of the Pain GitHub - duguyue100/midnight-captain: Inspired by Midnight Commander, tailored to my taste. How to build a `git diff` driver · Jamie Tanna | Software Engineer Center for Responsible, Decentralized Intelligence at Berkeley The Local Universe’s Expansion Rate Is Clearer Than Ever, but Still Doesn’t Add Up - A new synthesis of astronomical measurements confirms a persistent mismatch that could point to physics beyond current models The air throughout our homes is infused with microplastics. But there are things you can do to breathe less of them The disturbing white paper Red Hat is trying to erase from the internet – OSnews The Future of Everything is Lies, I Guess: Annoyances ‘Abhorrent’: the inside story of the Polymarket gamblers betting millions on war Productive procrastination — Max van IJsselmuiden maps, territory and LMs 447 Terabytes per Square Centimetre at Zero Retention Energy: Non-Volatile Memory at the Atomic Scale on Fluorographane Show HN: Pardonned.com – A searchable database of US Pardons 20 Years on AWS and Never Not My Job The Seasons are Wrong Artemis II crew splashes down near San Diego after historic moon mission We gave an AI a 3 year retail lease in SF and asked it to make a profit | Andon Labs How a dancer with ALS used brainwaves to perform live On filing the corners off my MacBooks Installing every* Firefox extension OpenClaw’s memory is unreliable, and you don’t know when it will break Steve Blank Nowhere Is Safe Chimpanzees in Uganda locked in vicious 'civil war', say researchers watgo - a WebAssembly Toolkit for Go linux/Documentation/process/coding-assistants.rst at master · torvalds/linux GitHub - callumlocke/json-formatter: Makes JSON easy to read. Founding Product Engineer at Bild AI | Y Combinator A compelling title that is cryptic enough to get you to take action on it GitHub - Keychron/Keychron-Keyboards-Hardware-Design: Industrial design files for Keychron keyboards and mice. 100+ models with CAD assets in STEP, DXF, DWG, and PDF. Source-available, with commercial use allowed for original compatible accessories within the license terms. [ANNOUNCE] WireGuardNT v0.11 and WireGuard for Windows v0.6 Released 1D-Chess Helium Is Hard to Replace Cooperative Vectors Introduction | Evolve Keeping a Postgres queue healthy — PlanetScale Our response to the Axios developer tool compromise Do Americans read print books, e-books or audiobooks more? The Zettelkasten Method in Obsidian: A Practical Setup Guide Artemis II Is Competency Porn and We Are Starving For It WeakC4 Flight Viz — Cockpit View A Mexican surveillance giant you’ve never heard of is now watching the U.S. border Surelock: Deadlock-Free Mutexes for Rust RISC-V 101 – what is it and what does it mean for Canonical? | Ubuntu The Problem That Built an Industry How Much Linear Memory Access Is Enough? | Solidean Investigating Split Locks on x86-64 Simplest hash functions Sybilproof reputation mechanisms (2005) [pdf] What is a property? How Complex is my Code? Static code analysis in Kotlin — tools overview Toffoli gates are all you need PGLite evangelism dcmake: a new CMake debugger UI Clojure on Fennel part one: Persistent Data Structures Fragments: April 2 Python Release Python install manager 26.1 The Life and Death of the Book Review - Liberties Introducing Database Traffic Control — PlanetScale Bitcoin miners are losing $19,000 on every BTC produced as difficulty drops 7.8% God sleeps in the minerals Building slogbox Apple Silicon and Virtual Machines: Beating the 2 VM Limit Who was “Not Even Wrong” first? Pokemon Evolution Vs Darwinian Evolution The APL Programming Language Source Code
Learn Something Old Every Day, Part XXI: VGA Memory Access Is Complicated
2026-05-10 · via Hacker News

Last week I had another run-in with VGA emulation, and like last time, the cause was very likely the generally woefully inadequate VGA documentation.

The VGA is not, all things considered, a particularly complicated piece of hardware. It has no microcode, no CPU/microcontroller, and performs relatively simple functions. However, the VGA does consist of several logically separate components that work together, and this creates a perhaps underappreciated level of complexity.

By far the biggest difficulty in implementing VGA hardware or emulation is the lack of detailed and accurate documentation. The problem really started with the IBM EGA, because the VGA is only a slightly extended superset of the EGA.

The IBM EGA (Enhanced Graphics Adapter) was designed to support high-resolution (by 1984 standards) graphics in up to 16 colors, programmable fonts, but also with a high degree of compatibility with MDA/CGA text as well as CGA graphics modes.

However, the EGA is not register compatible with the earlier IBM adapters (and its internal architecture is quite different). Using code that directly sets up a CGA graphics mode (for example) will not work on an EGA. What does work is using the BIOS to establish the mode and then accessing video memory as if it were a CGA.

At the same time, the EGA is old enough that it was not a single integrated chip. It was built from four core chips: Graphics Controller, Sequencer, Attribute Controller, and CRT Controller. Each of these chips had its own set of registers.

The difficulty with EGA/VGA documentation is that the vast majority of it (starting with IBM’s own Technical References) is written for someone using a VGA, not implementing VGA functionality. And it is written with the assumption that the user is primarily interested in standard modes supported by the BIOS.

Most VGA references then say things like “for text modes, set bit X to 1 and bit Y to 0”. Which is useful enough if one wants to program text modes, but it does not at all explain what the bits actually do. Because the EGA consisted of several chips, it is common that bits in two or three chips have to be set certain way to achieve, say, CGA text mode compatibility or CGA graphics compatibility. Obviously each bit does something different, but users are “supposed” to set them all together. At the same time nothing actually stops programmers from flipping one or two bits out of a set of three, and then what happens? Some of the “undocumented” combinations turn out to be quite useful, such as the famous VGA Mode X.

The problem I tried to solve was related to the Odd/Even control registers in the VGA (or EGA, really) Sequencer and Graphics controller. Odd/Even access is used for text modes, and the name references the fact that the character codes are stored in even bytes and attributes in odd bytes, although really they’re stored in separate planes of the EGA/VGA four-plane memory organization.

IBM…

To compare, let’s see what the IBM VGA Technical Reference Manual (TRM) says about these bits:

  • SR4[2], bit OE: When the Odd/Even field (bit 2) is set to 0, even system addresses access maps 0 and 2, while odd system addresses access maps 1 and 3. When set to 1, system addresses sequentially access data within a bit map, and the maps are accessed according to the value in the Map Mask register (hex 02).
  • GR5[4], bit OE: When set to 1, the Odd/Even field (bit 4) selects the odd/even addressing mode used by the IBM Color/Graphics Monitor Adapter. Normally, the value here follows the value of Memory Mode register bit 2 in the sequencer.
  • GR6[1], bit OE: When set to 1, the Odd/Even field (bit 1) directs the system address bit, A0, to be replaced by a higher-order bit. The odd map is then selected when A0 is 1, and the even map when A0 is 0.

These three bits are all called ‘OE’ in the documentation. Note how the GR5[4] description does not really say anything, except that the GR5[4] value should “follow” the SR4[2] value. The GR6[1] documentation says what happens when the bit is set to 1, but does not explicitly say anything about setting the bit to 0.

From these descriptions, it’s next to impossible to divine what those bits do individually, just that they all need to be set a certain way to emulate CGA text or graphics modes.

Most VGA programming books and chip datasheets are similar to IBM’s documentation. The description is not wrong but it is rather inadequate. Fortunately, not all references are like that.

… vs Compaq

An unexpected source of helpful information turned out to be Compaq’s EGA TRG (Technical Reference Guide).

Here’s how Compaq documented the same bits (in the EGA, but they work the same on the VGA):

  • SR4[2]:
    0 = Even-numbered CPU addresses access planes 0 and 2. Odd-numbered CPU addresses access planes 1 and 3.
    1 = CPU addresses access data sequentially in the planes
    Bit <2> (odd/even bit) controls ONLY the CPU write accesses. CPU read accesses are controlled by the odd/even bit in the Graphics Controller Mode register.
  • GR5[4]: Odd/even bit
    0 = CPU reads data sequentially from the planes
    1 = Even CPU addresses access planes 0 and 2. Odd CPU addresses access planes 1 and 3
  • GR6[1]:
    0 = CPU address A0 is used as video memory address bit <0>
    1 = CPU address A0 is replaced by a higher CPU bit or the page select bit (bit <5>) from the Control and Status Miscellaneous Output register

In addition, register GR4 (Graphics Controller Read Plane Select) documentation has a handy table showing exactly how the GR4 register and the GR5[4] bit interact to determine read plane selection.

Compaq’s documentation is superficially similar to IBM’s but explains vastly more. It clearly states that SR4[2] controls CPU writes while GR5[4] controls reads. The bits have distinct and separate functionality, even if they are usually programmed in tandem.

Compaq also explains that while SR4[2] and GR5[4] control plane selection for writes and reads, respectively, bit GR6[1] controls addressing. In other words, GR6[1] determines which memory address is accessed, and SR4[2] with GR5[4] control which of the four planes at that memory address will be accessed, but separately for writes and reads.

As one might suspect, the three separate bits do in fact have separate functionality—which is hardly surprising, because if they didn’t, IBM wouldn’t need three of them. As an aside, these bits only control how VGA memory is read and written by the host CPU. There’s another, completely separate set of bits in the CRT Controller (CRTC) which determines how the data in VGA memory is displayed on the screen.

Honestly, thank you Compaq for taking the time to explain what the bits really do, instead of just vague hand-waving about how they’re meant to be used.

Questions Remain

Even the Compaq documentation is not complete. The GR6[1] documentation states that address bit A0 (coming from the CPU) “is replaced by a higher CPU bit or the page select bit”. But it doesn’t say which higher CPU [address, presumably] bit, or how the hardware decides whether to use a CPU address bit or the MSR[5] bit.

I found the answer in the Matrox MGA-1064 specification (when it comes to VGA registers, it’s very similar to MGA-2164, Matrox G100, G200, and similar documents). Matrox describes the GR6[1] bit as follows:

  • Odd/Even chain enable. VGA.
    0: The A0 signal of the memory address bus is used during system memory
    addressing.
    1: Allows A0 to be replaced by either the A16 signal of the system address (if memmapsl is ‘00’), or by the hpgoddev (MISC<5>, odd/even page select) field).

Well that is interesting. The memmapsl bits are GR6[3:2] and setting them to 00 means that the VGA decodes the entire A0000h-BFFFFh range. This setting is very unusual and in practice not used. But it actually makes sense.

The VGA (and EGA) has (or can be upgraded to, in case of EGA) 256K memory. However, due to the way it’s organized as four separate planes, there are only 64K unique addresses, each address with four planes behind it (eight bits per address on each of the four planes). When Odd/Even addressing is enabled, only every other address in VGA’s memory is accessed, because the A0 bit is fixed (that is, it does not come from the CPU). When the GR6[3:2] bits are programmed to 00, a 128K range can be used to access 64K unique addresses… which at first glance doesn’t make sense—except setting GR6[1] to one allows the user to access all even addresses in the 64K range through A0000h-AFFFFh and all odd addresses through the B0000h-BFFFFh range. And that is accomplished precisely by replacing the A0 bit coming from the CPU (which usually controls the odd/even plane select in text modes) by A16.

When the GR6[3:2] bits are set to a value other than 00 (decoding either 64K or 32K of address space), MSR[5] becomes the “page select” bit instead, allowing the user to choose which 64K are accessed.

The MSR[5] bit is remarkably poorly documented and different sources disagree on its polarity. Some (e.g. Matrox) claim that setting MSR[5] bit to 1 selects the “high page”, some (e.g. ATI 264VT, Cirrus Logic Alpine) claim that 1 selects the low page. Everything is further confused by the fact that the MSR[5] bit defaults to 0 after hardware reset, but just about every EGA/VGA BIOS sets it to 1.

Needless to say, there are also completely separate CRTC control bits which govern how data in VGA memory gets to be displayed. Bits CRTC14[6], CRTC17[0], CRTC17[1], CRTC17[5] and CRTC17[6] control how the CRTC addresses memory when it refreshes the display. The Matrox documentation of CRTC17 includes three handy tables showing how the CRTC bits transform the CRTC counter (16-bits, A0-A15) into memory address bits (MA0-MA15) in rather interesting ways.

The CRTC’s word access mode was clearly designed as a counterpart to the Odd/Even CPU addressing—although of course nothing forces programmers to use the two together. In word access mode, CRTC address bit A15 (assuming address wrapping is not forced by setting CR17[5] to zero) becomes memory address bit MA0. This mechanism lets the CRTC display even addresses in VGA memory when the CRTC address is in the 0000h-7FFFh range and odd addresses in the 8000h-FFFFh range. That neatly maps to the functionality provided by GR6[1].

I am not aware of any software actually using MSR[5] or the 128K VGA address range to increase the memory capacity of EGA/VGA text modes. Then again, the bits are there, and it’s almost guaranteed that some enterprising programmer used them.

Whether all of these bits even work on common VGA implementations is yet another question. The incomplete documentation likely prevented programmers from getting creative, which in turn hid problems caused by incomplete or inaccurate VGA implementations.

Why It’s Complicated

The above paragraphs illustrate why the VGA (and EGA) is complicated. There isn’t a single “Enable Text Mode” bit. There’s one control for CPU memory writes, another for CPU memory reads, another for CPU memory addressing. And then there’s a whole another set of bits that control the CRTC operation.

Under typical circumstances, these bits are programmed as a unit during a BIOS mode set. Yet all of these bits can be toggled individually, which creates a fairly large number of “undocumented” combinations. Because these combinations are not thought to be useful, the vast majority of VGA reference material just glosses over the details.

The catch is that programmers can and do tweak the individual bits, which means that in order to achieve a 100% (or at least very high) degree of compatibility, VGA hardware or emulation needs to correctly implement the behavior of every single bit. But without adequate documentation, that’s not a trivial task.