• Please review our updated Terms and Rules here

EGA PEL panning & scanlines

Mills32

Experienced Member
Joined
Sep 25, 2018
Messages
149
Location
Spain
I read this old post about EGA: https://forum.vcfed.org/index.php?threads/ega-video-corruption.43557/post-585123

...
On EGA and the Paradise PVGA1A, and maybe others, display start is latched at the falling edge, and PEL panning is NOT LATCHED AT ALL. PEL panning can be updated while visible scanlines are put out and the change is seen immediately (or at scanline start). The game Beverly Hills Cop (by Tynesoft) uses this to show a screen with text with sine wave effect. This works on EGA but not on VGA (except on the Paradise card).
...
I tried modifying EGA PEL panning without waiting for vsync, and my attempt to make a wave effect failed (Dosbox, PCem, 86Box).

So does this mean all emulators are wrong?. I can't test a real EGA.

Thanks.
 
Beverly Hills Cop is a good test. Here is what it's supposed to look like:


If the whole screen shakes, then it's not emulating EGA correctly.
 
I just checked and you are right, none of those emulators are implementing pel panning correctly for EGA.
 
So I should post an issue for the emulators :). And maybe some VGA cards support the effect.

I just tested dosbox-x and it works there, But my program did nothing, I don't know if they are using PEL panning or the start address register, I have to do more tests.

I set the cpu to 200 / 300 cycles on dosbox-x (an 8088 more or less at 7 mhz) and the animation is not slowing down (that means it is not redrwing the whole screen). But it does not look right because they are surely waiting for horizontal retrace using out instructions, and that's too slow fot the 8088.

EDIT: I can confirm Dosbox-X is implementing the EGA PEL panning right, and I managed to create a little program that makes an image wavy using PEL panning :). I'll post it later.
 
Last edited:
game_000.png

There you have it, It works with around 380 cycles on dosbox-x, (that's more or less an 8086-8MHz). To make it work on 8088s we have to calculate the cycles for every EGA scanline, (like they did for CGA, and the 8088mph / area5150 demos).
 

Attachments

  • scanlines.zip
    16.2 KB · Views: 3
To make it work on 8088s we have to calculate the cycles for every EGA scanline, (like they did for CGA, and the 8088mph / area5150 demos).

Cycle-counting sounds like overkill for this purpose. Why not poll the status register at 3DAh for bit 0 (retrace) to detect the overscan period of each scanline, and make your changes then? Many parts of 8088 MPH and Area 5150 use this method for CGA as well (others do require cycle-counting, but for different reasons).

What I'd like to know is, how this effect could be replicated on those VGA cards that do latch the Pel Panning register. Pretty sure someone could turn up an old demo that did this...
 
Cycle-counting sounds like overkill for this purpose. Why not poll the status register at 3DAh for bit 0 (retrace) to detect the overscan period of each scanline, and make your changes then? Many parts of 8088 MPH and Area 5150 use this method for CGA as well (others do require cycle-counting, but for different reasons).

What I'd like to know is, how this effect could be replicated on those VGA cards that do latch the Pel Panning register. Pretty sure someone could turn up an old demo that did this...

I can't test this on a real PC, your idea should be fast enough for the 8086 4.77 (on Dosbox-x it worked with a 200 cycle CPU). I'd also love to see this on VGA cards, and also a way to update the start address offset every scanline, (to make huge fake parallax).

I posted a bug on 86Box emulator, it is supposed to work on nightly builds, but it did not work for me, (anyway they are surely adding it).

This is the last version, I don't know if it is faster this way or not:
Code:
    asm mov cx,200       //Number of scanlines to wave
    asm mov bx,0x3301    //bl = 0x01 (H sync bit); bh = 0x33 (palette normal operation | Pel panning reg from ACR)
    asm mov ax,0x03DA    //H/V sync register
    asm mov es,ax
    asm mov di,0x03C0    //ACR Attribute Controller Register
    asm lds si,wave      //an array with sine wave values
 
    asm cli
    _loop:
        //Wait Hsync
        asm mov    dx,es
        WaitNotHsync:
            asm in al,dx; asm test al,bl;
            asm jnz WaitNotHsync;
        WaitHsync:
            asm in al,dx; asm test al,bl;
            asm jz WaitHsync;

        //Write PEL panning
        asm mov dx,di
        asm mov al,bh        //0x20 | 0x13 (palette normal operation | Pel panning reg)
        asm out dx,al
        asm lodsb            //load value from table at ds:[si]; inc si
        asm out dx,al
        asm loop _loop

    asm sti
 
Last edited:
Just realized EGA cards on mode 0D, work with 200 real scanlines, and slow CPUs can read hsync and wait. But VGA cards output 400 scanlines, so it is not possible for slow CPUS to handle this kind of code unless you configure the card to output 15KHz, and most modern monitors won't support it.
 
For VGA you just need to wait for 2 hsyncs per iteration, i.e. EGA and VGA need their own loops. I'm using that technique for a copper bar effect in mode x0d somewhere, changing the background color every other 2 scanlines.

I always thought that the offset register and PEL only took effect on VGA during vblank, never tried PEL per scanline on VGA. Might give it a go. I don't have a real EGA unfortunately.
 
For VGA you just need to wait for 2 hsyncs per iteration, i.e. EGA and VGA need their own loops. I'm using that technique for a copper bar effect in mode x0d somewhere, changing the background color every other 2 scanlines.

I always thought that the offset register and PEL only took effect on VGA during vblank, never tried PEL per scanline on VGA. Might give it a go. I don't have a real EGA unfortunately.
I was programming copper bars for VGA, they require at least a 286 to wait 2 scanlines. Scanlines are drawn too fast for slower cpus to get the hsync on time, using in/out instructions and loops.
 
I don't think there is such thing as correct implementation of DS and HS latching. Or maybe correct = identical to original IBM EGA, but correct != compatible, since many manufacturers implemented latching behavior differently.

(IBM implementation was one of the worse ones, so can't say that IBM behavior would have been good, and others worse)

Some months ago, I was investigating this behavior, and came up with the following table: https://www.vogons.org/viewtopic.php?p=1190977#p1190977
 
If an emulator is claiming to implement IBM EGA, then the correct implementation is the one that matches a real IBM EGA.

The behavior of various clone cards, or even the IBM VGA is irrelevant.
 
pel_pan_bhc..png

Thanks for the example, wanted to check my own emulator. Hard to find things that test the pel pan register besides Command Keen.

Oddly enough this effect runs too fast compared to the example video. I wonder if it's using the EGA vsync interrupt for synchronization? The characters also seem to skew more then 8 pixels in the video, so I imagine they're doing a trick with the start address as well; not sure why I'm not picking it up.
 
Seems like the effect is pretty CPU speed dependent. Maybe intended for AT class machines?
 
View attachment 1270154

There you have it, It works with around 380 cycles on dosbox-x, (that's more or less an 8086-8MHz). To make it work on 8088s we have to calculate the cycles for every EGA scanline, (like they did for CGA, and the 8088mph / area5150 demos).

Works well on 8088 here:
 

Attachments

  • melt_04.gif
    melt_04.gif
    430.6 KB · Views: 8
Back
Top