keenmaster486 wrote on 2023-05-07, 21:32:
Okay, I really want to increase my limited understanding and figure out how this actually works. I'm having trouble wrapping my head around it. So what you guys are telling me is that the horizontal scrolling is different from the vertical scrolling, because the pan register only finetunes the horizontal scrolling, so you have to increment that by 1 each frame until it reaches the end of the 8-pixel wide vertical column (so to speak), and then you can increment the start address - am I thinking correctly about this?
Yes. That's exactly how it works.
keenmaster486 wrote on 2023-05-07, 21:32:
In this video, John Carmack talks about his scrolling routines (starting at 2:24). He mentions having a "64K window" - the amount of video memory in the EGA card, I assume.
The 64K window is actually the full 256KB of EGA memory. The EGA memory architecture is quite arcane, by having 65536 words of 32 bits each. In the graphics mode, each byte access performed by the CPU in the range A000:0000 to A000:FFFF (the 64K window) interacts with the corresponding 32-bit word of video memory. In the most simple setup, for reading, you select which 8-bit part of the 32-bit word you want to read before you do the actual read access, and for writing, you select which of the 4 8-bit parts should receive the value written. The real power of EGA programming is fully understanding the architecture and optimizing drawing code for it. As this post is not about EGA drawing, but about EGA scrolling, I will stop this thread of discussion here.
keenmaster486 wrote on 2023-05-07, 21:32:
I found some info on the EGA bitplanes that clear up how they work a little for me: the card is fetching 32 bits at a time from memory because it's fetching one byte from each bitplane, making 32 bits or 4 bytes total.
"bit plane" is a common term for the 4 8-bit parts of the 32-bit EGA memory words. This term makes a lot of sense, because in 16-color mode, each of the 4 bytes contains information for one of four bits making up the pixel color.
keenmaster486 wrote on 2023-05-07, 21:32:
Here's the main head-twister I can't understand right now: memory addresses are linear, obviously. I assume the EGA card reads one scanline's worth of memory before moving to the next line. If I increment the start address by 1, won't it cause a shear effect as every other row is now offset since it still grabs 320 pixels or 160 bytes of video memory, cutting into the beginning of the old next row before moving to the next line?
One key advantage of the EGA CRTC card over the CGA CRTC (the classic motorola 6845) is that the EGA CRTC can be programmed to skip a certain amount of video memory between two lines. This means that in 320x200 mode, the next line does not necessarily start 40 words after the previous line. The logical line length can be set to 80 words (320 bytes if you count in bytes, but you should stop doing that when trying to understand the EGA architecture), so 40 words (320 pixels) are displayed, and the next 40 words (again 320 pixels) are skipped. This means that continoously increasing the start address from word 0 to word 40 will not "tear around" contents of the second line into the first line.
The key point of adaptive tile refresh is that you just need like 8 or 16 pixels left and right of the currently visible screen. Let's say you program the video card to 48 words per line, that is 384 pixels worth of data per line. You only display the central 320 pixels, and have 32 pixels left and right of that window in video memory. Then you scroll 16 pixels to the right. Now you only have 16 more pixels to the right, but 48 pixels to the left. You then replace the 16 leftmost pixels by the content the is supposed to be right of the visible window, to go back to 32 pixels to the right and 32 pixels to the left.
keenmaster486 wrote on 2023-05-07, 21:32:
1. The fact the game is pageflipped - he'd have not one, but two pageflipped screens both scrolling, which since a 320x200x4bit screen is 32,000 bytes, I assume would take up almost all of the EGA video memory. I can kind of envision how this would work but I don't think I'll get it until I figure out the answer to my question above about how EGA translates linear memory into a screen with rows.
At 320x200, a line takes 40 EGA words (of 32 bits), so the complete image takes 8000 words, using 8000 of the 65535 addresses available in EGA memory space. You can get more than 8 pages into that space, even if you add some margin so pixel-precision scrolling works. The amount of EGA memory is not a problem for that refresh algorithm.
keenmaster486 wrote on 2023-05-07, 21:32:
2. The SVGA compatibility problem, stating that on some SVGA cards, moving the start address past the end of the 64K EGA memory would not wrap around, but would bring it into uninitialized memory and display garbage, so his solution was to have a compatibility mode that moves the start address back to the beginning and copies the entire screen, producing a "hitch". I've never personally observed this hitch; I think you'd have to have a slow 286 with SVGA compatibility mode enabled to see it. I'll have to try that sometime.
Exactly. Although the number of SVGA cards requiring this compatibility mode is quite low. I didn't run into one yet.
keenmaster486 wrote on 2023-05-07, 21:32:
For what it's worth, regarding the 60Hz vs 70Hz issue, I have a regular EGA card with an IBM 5153 in my PC/AT, and I've never noticed anything wrong with the scrolling. The game also runs at the correct speed, which is interesting to me since I was under the impression that the game uses the VGA 70 Hz vertical sync for its internal timer, dividing it in two for 35 fps.
The game will not run at the intended ("correct") speed. It will divide the vertical sync rate by two, so it will run at 30 fps on EGA cards and 35 fps on VGA cards. As it will run as smooth at 30 fps on EGA cards as it runs at 35 fps on VGA cards, it's likely that you didn't notice the 16% speed decrease of the game.