[MS] How did code handle 24-bit-per-pixel formats when using video cards with bank-switched memory? - devamazonaws.blogspot.com

On the topic of what happens if an access violation straddles multiple pages, Gil-Ad Ben Or wonders how code handled 24-bit-per-pixel formats when using video cards with bank-switched memory. "The issue is that since 64k bytes is not divisible by 3, and you usually need a pixel granularity if you aren't using some kind of buffering."

This is referring to an older article about the Windows 95 VFLATD video driver helper which emulated a flat video address space even though the underlying video card used bank-switched memory by mapping the active bank into a location in the address that corresponds to its emulated flat address, and responding to page faults by switching banks and moving the mapping to the emulated flat address of the new bank.

The trick falls apart if somebody makes a memory access that straddles two banks, because that leads to an infinite cycle of bank switching: The CPU raises an access violation on the first bank, and the driver maps that bank in and invalidates the second bank. But since the memory access straddles two banks, then the CPU raises an access violation on the second bank, and the act of remapping that bank causes the first bank to become unmapped, and the cycle repeats.

So how did code deal with pixels that straddles two banks?

The underlying rule is that all accesses to memory must be properly-aligned. No properly-aligned memory access will straddle a page boundary.

Managing this requirement was just the cost of doing business. People who wrote code that accessed video memory knew that they couldn't use tricks like "read a 32-bit value and ignore the top 8 bits." If you have a pixel that straddles a boundary, you'll have to break it up into three byte accesses, or at least a byte access and a word access (where the word access is properly aligned). In practice, it's not worth the effort to do the work to decide whether to split the pixel as byte+word vs. word+byte, and everybody just did it as three bytes.

Now, if you were operating on an entire row of pixels, you could use aligned 32-bit reads and writes to access the entire row: Copy bytes until the address is 32-bit aligned, and then use 32-bit reads for the bulk of the row, and then copy any leftover bytes at the end. The 32-bit reads will straddle pixel boundaries, but that's okay because they don't straddle page boundaries.

In other words, the answer is that they handled it by handling it.


Post Updated on April 20, 2026 at 03:00PM
Thanks for reading
from devamazonaws.blogspot.com

Comments

Popular posts from this blog

[MS] Pulling a single item from a C++ parameter pack by its index, remarks - devamazonaws.blogspot.com

[MS] Going beyond the empty set: Embracing the power of other empty things - devamazonaws.blogspot.com

[MS] The case of the crash when destructing a std::map - devamazonaws.blogspot.com