Closed mras0 closed 2 years ago
Amazing. Seems like the whole screen is drawn by the Copper.
I think the graphics glitch is not a bug. It is also visible in UAE if the screen geometry is switched to "Extreme" (just notices that I am still running 4.9.0, need to check if this makes a difference...):
On my A500, there is no visible glitch, because the erroneous stripe is outside the visible area. If vAmiga is run with the same screen geometry as my TFT, it looks just fine, too.
BTW, I've written a bunch of new test cases that verify BPLCON1 behaviour in the overscan area (overscan1
- overscan6
, overscan1b
- overscan6b
).
Update: Same in UAE 4.9.1
sorry, yes, you're right about the gap being in the non-visible area. The part appears to be a "standard" BPL1CON "compression", btw like the bouncing logo in Desert Dream (writing lower and lower values to BPLCON1).
Second issue I think is this part:
00038c34 3d40 0058 MOVE.W D0, $0058(A6) ; Start blit
00038c38 43fa 002e LEA.L $002e(PC), A1 ; A1 := $00038c68
00038c3c 21c9 006c MOVE.L A1, $006c.W
00038c40 3d7c c040 009a MOVE.W #$c040, $009a(A6) ; Enable blitter interrupt
00038c46 0440 0040 SUB.W #$0040, D0
00038c4a 3340 0038 MOVE.W D0, $0038(A1) ; Update blitsize in interrupt code
00038c4e 2228 003c MOVE.L $003c(A0), D1
00038c52 7400 MOVEQ.L #$00, D2
00038c54 3428 000c MOVE.W $000c(A0), D2
00038c58 d481 ADD.L D1, D2
00038c5a 2341 0002 MOVE.L D1, $0002(A1)
00038c5e 2342 000c MOVE.L D2, $000c(A1)
00038c62 2342 0016 MOVE.L D2, $0016(A1)
00038c66 4e75 RTS
00038c68 23fc 0000 0000 00df f04c MOVE.L #$00000000, $00dff04c.L
00038c72 23fc 0000 0000 00df f050 MOVE.L #$00000000, $00dff050.L
00038c7c 23fc 0000 0000 00df f054 MOVE.L #$00000000, $00dff054.L
00038c86 42b9 00df f062 CLR.L $00dff062.L
00038c8c 23fc 0d3c 0000 00df f040 MOVE.L #$0d3c0000, $00dff040.L
00038c96 33fc 4040 00df f09c MOVE.W #$4040, $00dff09c.L
00038c9e 33fc 0000 00df f058 MOVE.W #$0000, $00dff058.L
00038ca6 21fc 0003 8cb0 006c MOVE.L #$00038cb0, $006c.W
00038cae 4e73 RTE
In WinUAE I can see that the interrupt is triggered after the SUB.W
instruction at 00038c46
while at least in my emulator it's only after the blit size is updated => Corruption of all interrupt vectors and a messy end shortly after. Likely same or similar issue in vAmiga.
Made a quick test. It's green in WinUAE and blue in vAmiga indicating interrupt happens too fast. That's actually the opposite of what I was expecting, but a difference none the less. intena.zip
It's green in WinUAE and blue in vAmiga
On my A500, the winner is cyan:
I'll add a INTENA timing tests with a properly synced CPU to the test repo (although your btst
syncing code should be enough in this test case). If I remember correctly, I've never written any timing test for this register.
Very interesting, so actual time is (probably) even longer? Of course, the issue might be different in vAmiga, but since I got this debug output if figured it was very close:
[4038] ( 9,200) 038C9E 0 BCBSDA 6044 17A2 XFILES: Overwriting existing Blitter event
[4038] ( 13, 32) 00001C 6 BCBSDA 6044 37A2 XFILES: lineFException(ffff)
Looked at the IPL timing of SUBI.W #...,Dn
in WinUAE and IPL fetch happens before prefetch which is why I guessed that the issue was interrupt triggering too late.
I didn't figure I needed any elaborate sync for the test, since I just wanted VERTB set in INTREQ (of course could have just set it myself or something similar) and thought only time from INTENA write to interrupt mattered.
Made a quick test.
You've implemented an interesting test case here. I've written some INTENA / INTREQ (enatim1 - enatim4) tests for which I thought they would catch everything your test catches, but they don't.
A major difference is that my tests utilise the Copper to write into INTENA / INTREQ. Needs more investigation later this week...
I haven't found any IPLissue w.r.t the SUB instruction either. I've modified the existing IPL/ADD1.w test by replacing all ADDs with SUBs. As expected, the test image remained the same. Bottom. line: There is no difference between ADD and SUB.
I didn't figure I needed any elaborate sync for the test, since I just wanted VERTB set in INTREQ
If I remember correctly, the VERTB interrupt is signalled at (0,0). There is memory refresh DMA going on in cycles 1,3,5 which might possibly interfere. I am not sure if this could really make the test case indeterministic, but it might be safer to run the code sequence in the middle of the scanline.
I've written two more tests which basically mimic the INTENA test written by @mras0 (enabling IRQ by letting the CPU write into INTENA
and running a MOVE reg,reg
chain afterwards).
Despite some strange OCS / ECS difference (see #709), vAmiga does it right (it matches the ECS output pixel by pixel).
After running out of options, I decided to run the mras-test again on both of my stock ECS and OCS machines. On these machines, I get a different result. The winner is "blue" on both:
Summary:
More findings: I tried to run IPL test IPL/S/SUB1w.adf
in UAE. For whatever reason, the ADF does not boot. If include "ministartup.s"
is commented out, it boots. However, it's completely off. My CPU sync code does not manage to stabilise the CPU in UAE which results in a flickering image. Here is a still:
vAmiga:
This is the reference image (A500 OCS):
The discrepancies mean that UAE either uses wrong IPL timing for the SUB command or the mismatch is due to a more general interrupt timing issue.
Putting all together, there is another hypothesis we might have to consider: Maybe vAmiga does the right thing (i.e., modifying a Blitter register while the Blitter is active) and crashes because it does not handle this case correctly.
A500 with ACA500plus: Cyan Ah, yes, that would explain it. I only considered A500 + maybe slow ram when writing the test. That will teach me to throw something together quickly.
Since I last posted the post on EAB has been updated, and latest WinUAE beta now also shows blue in my test. So vAmiga was right all along.
Putting all together, there is another hypothesis we might have to consider: Maybe vAmiga does the right thing (i.e., modifying a Blitter register while the Blitter is active) and crashes because it does not handle this case correctly.
Yes, I asked Ross (Guru from EAB), and while I located the right place where things go wrong my diagnosis was incorrect. It's not related to interrupt timing, but as you guessed, it's because of the write to BLTCON0. Apparently that change causes blitter channel sequence to change to BAC (i.e. no longer writing to D). In other words this crash is expected until "blitter accuracy=3" is supported.
Sorry for the wild goose chases! You can close this one and maybe just leave a mention in #647.
IPL/S/SUB1w.adf is stable in 4.9.1 with A500 "Most common" configuration for me. Config I'm using:a500.zip
Looks like this:
In latest (unstable) beta:
Sorry for the wild goose chases!
That's totally fine. Although there was no bug to fix, it was worth debugging. Firstly, the test suite grew by a few more tests which is good. Secondly, by reviewing my own code, I've seen that I need to verify the timing of the Copper COPJMP instruction. Thirdly, I've levelled up by peeking into your test cases. E.g., I wasn't aware that there is a rep
command which allows me to shorten my assembler sources quite a bit in future.
Pouet link ADF: TekRampage.zip
Works in WinUAE 4.9.1 with classic A500 quickstart (KS1.3/512K chip/512K slow) and on my real A1200. Note that I tested it because it was mentioned in the "Problematic Demos" thread on EAB (probably for a good reason).
Just tested a few configs (including vAmigaWeb) and issues are the same. (It also crashes in my emulator, but haven't debugged it).