tonioni / WinUAE

WinUAE Amiga emulator
http://www.winuae.net/
542 stars 87 forks source link

DDF logic #170

Open dirkwhoffmann opened 4 years ago

dirkwhoffmann commented 4 years ago

I wrote a couple of test cases to find out how the DDF circuitry works (i.e., if it was really designed as a state machine or if the visible behaviour is just a combination of some toggling flip-flops).

UAE is pretty close (e.g., by accurately replicating the OCS scanline effect), but it doesn’t seem to be 100% right.

Here are the results of test case: https://github.com/dirkwhoffmann/vAmigaTS/tree/master/Agnus/DDFNEW/single1

Original Amiga 500 (ECS Agnus): 🥰

single1_A500_8A

UAE (ECS Agnus): 😳

Bildschirmfoto 2020-03-03 um 18 28 43

The Copper list is pretty simple. Between blocks of normal DDF values, it assigns the same value to DDFSTRT and DDFSTOP. Here is a fraction of the list:

        dc.w    $4801,$FFFE  ; WAIT 
    dc.w    COLOR00, $F00
    dc.w    COLOR01,$B6F
    dc.w    DDFSTRT,LEFT
    dc.w    DDFSTOP,RIGHT
    dc.w    $48D9,$FFFE  ; WAIT 
    dc.w    COLOR00, $000

    dc.w    $4E01,$FFFE  ; WAIT 
    dc.w    COLOR00, $F00
    dc.w    DDFSTRT,$28
    dc.w    DDFSTOP,$28
    dc.w    $4ED9,$FFFE  ; WAIT 
    dc.w    COLOR00, $000

    dc.w    $5401,$FFFE  ; WAIT 
    dc.w    COLOR00, $F00
    dc.w    DDFSTRT,LEFT
    dc.w    DDFSTOP,RIGHT
    dc.w    $54D9,$FFFE  ; WAIT 
    dc.w    COLOR00, $000

    dc.w    $5A01,$FFFE  ; WAIT 
    dc.w    COLOR00, $F00
    dc.w    DDFSTRT,$30 
    dc.w    DDFSTOP,$30
    dc.w    $5AD9,$FFFE  ; WAIT 
    dc.w    COLOR00, $000

Overall, the DDF logic seems to be tricky. Yet I cannot explain at all what I see on the real machine. What UAE produces seems to be logical to me, but the real Agnus must follow some other, more esoteric rules.

tonioni commented 4 years ago

It is tricky. I have comment in UAE that says ECS DDSTOP wins if DDSTRT has same value (OCS = DDFSTRT wins) but it probably is only true when DDFSTRT has already matched and DDFSTRT was changed later in scanline. (This isn't that rare in demos, mostly accidental bugs in copper lists..) Behavior probably is different if DDFSTRT hasn't yet matched during the scanline.

OCS almost certainly has state machine that can't skip states and also DDFSTRT/STOP comparisons are only active if vertical display window is open (DIWSTRT/STOP matched) . ECS (and AGA) is simpler, no display window requirement, also possibly just inactive/active state flip-flops like you said. I am not sure why they changed it, probably related to ECS only programmed modes needing more flexibility.

(btw, about your test programs, could you also wrap your test programs in some good system take over routine to make them more compatible with different KS versions etc. At least LoadView(0)+2*WaitTOF() and disable all interrupts and DMA and then enable only required interrupts and DMA)

dirkwhoffmann commented 4 years ago

At least LoadView(0)+2*WaitTOF()

I've never written any 68000 assembler code back in the day. Therefore this sounds a little Chinese to me. I guess 2*WaitTOF() means that my code should wait two frames until it does something (TOF = top of frame)? 🤔 But what does LoadView(0) mean? 😶

I'll try to work on my tool-chain. Maybe I can produce better suited test programs with the Amiga Assembly VSC plug-in...

tonioni commented 4 years ago

They are graphics.library functions. Here are some links to example code: http://eab.abime.net/showthread.php?t=99010

graphics.library/LoadView(0) tells AmigaOS to switch off current mode, set chipset defaults. (=no RTG, no AGA special modes etc.. safe state for taking over the system)

tonioni commented 4 years ago

DDFSTRT==DDFSTOP seems to set internal logic to some kind of impossible state (for example both start and stop is active at the same time or something like that) because even if copper sets DDFSTRT or DDFSTOP to value later in scanline after first DDFSTRT/STOP value has matched, it won't affect current line at all, DDFSTRT/STOP logic seems to be stuck (normally in ECS you can have multiple DDFSTRT/STOP sections in single scanline. OCS does not support it. Demo Subtle Shades/Nuance. ECS=correct graphics. OCS=corrupted). Only following line works as expected. So I assume this impossible state only gets cleared when next scanline starts (or $18 special positions is reached)

EDIT: Forcing DDFSTOP match again (for example if DDFSTRT=$40,DDFSTOP=$40, wait for hpos>$40, set DDFSTOP=$80), when hpos reaches $80, stuck stop is "unlocked". After that DDFSTRT works normally again in same scanline.

Both start and stop being active at the same (and stop having priority) would explain this side-effect fully.

tonioni commented 3 years ago

Like https://github.com/tonioni/WinUAE/issues/179, this is now solved and correctly emulated. Note that result is quite different on OCS vs ECS. DDFSTRT/STOP logic is "interesting" and there are lots of differences between OCS and ECS/AGA.