First post, by Blackthorn00
I have the screen filled with 40x25 8x8 tiles and I'm trying to implement tile-based (NOT pixel based) scrolling. I want to scroll by 8 pixel at a time.
I'm using 86Box and an emulated 386SX with a ISA16 video card for testing.
I'm using mode 13h and basically I write in a memory buffer. Then I wait for the retrace and do a rep movsw to copy to VRAM. It mostly works, but there is a consistent flickering on around line 16-20. With movsd, the flickering line moves down.
What I think it's happening is that my movs gets an head start and then the beam catches up. I changed the retrace code to wait for a transition from 1 to 0 to avoid the head start (which I assume I got from the VBI time), but what I got is that the flickering line is now around row 6-8 instead. My guess is that it's the overscan that is giving me a headstart that I don't need. I really want to just be behind the beam, not ahead of it.
I kinda fixed my issue with the following code. Basically I wait for the retrace to finish (transition from 1 to 0) and then:
mov cx, 2000
skip_time:
loop skip_time
rep movsw
This fixes the problem. Basically I just wait for the beam to go ahead and then start the copy.
The issue is that that 2000 changes based on the processor. With a 486, it needs to be 12000, and various speeds of 386 need different values.
(BTW a 486DX/2 with PCI video card doesn't have this issue at all. Either there is no overscan or the copy is so fast that can finish during the VBI, 🤣).
I'm curious about how old games fixed this. I know about mode-x, but before Doom popularized it, games used plain 13h, and yet they managed to have no flickering at all.
One way I'm thinking is that, during startup, I could measure how long it takes between two retraces and then create a formula to retrieve the magic value to used in an active loop to wait for. That would work, I guess, but a better way would be to find a way to poll for the scanline and start the movsw only after the overscan is over. Is there a way to do this?
If not, I'll just bite the bullet and learn mode-x.