01 August 2021, 10:34 | #1 |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
COPPER interrupt causing slowdown - VERTB fine?
I've been investigating very slow load times in a game I'm patching in WHDLoad, and I've hit upon a strange situation I'm stumped by.
During loading, the game is mostly doing a lot of data unpacking in memory, while also displaying loading screen (5 bitplanes), and playing music. There is a level 3 interrupt routine that fires once every frame, triggered by COPPER interrupt in copperlist at VPOS $ff. This routine is responsible for setting screen colors for fade in/out, joystick reads, and music player. So far so simple. This interrupt routine also appears to be the cause of the slowdown. What's stumped me is If I change this interrupt to use VERTB instead of COPPER (i.e. change INTENA, and test for VERTB bit instead of COPPER), the slowdown is instantly fixed. There don't seem to be any side effects of using VERTB instead - music plays fine, fade ins/outs work fine, controls work fine. I could probably just go with this as a fix - but I'd really rather understand why using COPPER interrupt is so much slower! I believed I've ruled out the interrupt firing more often than it should - I added a counter to interrupt routine and it seems to be firing once per frame as expected. I'm wondering if the COPPER interrupt is occurring at a time when the CPU would have less DMA contention, and therefore moving it to VERTB gives the unpack code more memory cycles to use, but that's a wild guess based on my inexperience with how the CPU has to contend with DMA for chip memory access. (And would surprise me given what I've read about CPU generally being able to operate on alternate cycles with DMA anyway.) I'm expecting this initial post to mostly generate "more information required" responses, but I would be really interested in insights from devs more experienced with the intricacies of Amiga DMA and interrupt architecture. What I could mostly do with is advice on methods to try to diagnose where the slowdown is happening. I've tried adding a $dff180 modifier either side of the copper interrupt code to visually time it - doesn't seem to be running for more than a few raster lines most of the time. Certainly not enough to prove why it would be slowing the loading down! Last edited by DJ Mike; 01 August 2021 at 10:46. |
01 August 2021, 11:15 | #2 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
|
Perhaps it is also CPU polling vertical position somewhere? Missing it would cause large slowdowns.
|
01 August 2021, 11:19 | #3 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
Assuming that the IRQ is handled correctly in both cases and that the displayed 5-bitplane image is 200 pixels high and not 256, there is no difference in DMA litigation.
On the contrary, considering that Copper usually initializes the registers at the time of the VBI, the bus is even freer in the case of a line >$FF. Are you sure there are no precise line waits in the code outside the IRQ? (for which some frames are skipped because the line 'is not reached') EDIT: Toni preceded me, I write too slowly |
01 August 2021, 11:21 | #4 | |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
Quote:
Checking for line waits in the main code is a good call - I will investigate this. |
|
01 August 2021, 11:33 | #5 |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
Checked for reads to VP/VHPOSR - apart from my empty DBF loop replacements (which I disabled to rule those out!), game doesn't appear to be reading these. I've also checked for any extra INTREQ reads in case game is doing something silly with these, but none found outside of the interrupt routine itself.
|
01 August 2021, 12:51 | #6 |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
Some extra tests I ran via WinUAE debugger and observing visual heatmap :
- Skipping everything inside the IRQ code except INTREQ clear. No change - loading still slow. Game hangs when it reaches the end of its loading routine and tries to wait on VBL interval to do screen fade, but that's expected. - Disabling COPPER interrupt entirely (without using VERTB instead) - loading *speeds up!* So from my observation thus far, it is the fact that the copper interrupt fires at all that seems to cause slowdown. |
01 August 2021, 12:56 | #7 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
|
01 August 2021, 13:01 | #8 |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
From WinUAE debugger - this is the original $6c interrupt code:
Code:
000029C8 48e7 e0e0 MOVEM.L D0-D2/A0-A2,-(A7) 000029CC 302d 001e MOVE.W (A5,$001e) == $00dff01e,D0 000029D0 0800 0004 BTST.L #$0004,D0 000029D4 672a BEQ.B #$2a == $00002a00 (F) 000029D6 41f8 2988 LEA.L $2988,A0 000029DA 43f8 27bc LEA.L $27bc,A1 000029DE 303c 001f MOVE.W #$001f,D0 000029E2 32d8 MOVE.W (A0)+ [0000],(A1)+ [48e7] 000029E4 5449 ADDAQ.W #$02,A1 000029E6 51c8 fffa DBF .W D0,#$fffa == $000029e2 (F) 000029EA 6100 027e BSR.W #$027e == $00002c6a 000029EE 2078 2984 MOVEA.L $2984 [000050ea],A0 000029F2 4e90 JSR (A0) 000029F4 5279 0000 2de6 ADDQ.W #$01,$00002de6 [0023] 000029FA 50f9 0000 2e28 ST .B $00002e28 [00] (T) 00002A00 3b7c 0070 009c MOVE.W #$0070,(A5,$009c) == $00dff09c 00002A06 4cdf 0707 MOVEM.L (A7)+,D0-D2/A0-A2 00002A0A 4e73 RTE The fact that it ACKs all level 3 interrupts was not significant (although helpful when I changed routine to run on VERTB as I didn't need to fix the code ). |
01 August 2021, 13:06 | #9 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
Quote:
It depends if someone 'externally' check these bits. The clean is made at different point in time if Copper or VBI cause IRQ.. Is INTENA properly set? And A5? |
|
01 August 2021, 13:09 | #10 | |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
Quote:
I looked for any other reads to $DFF01E/INTREQR and found none. Heck, I put a watch on the entire DMA address space from $dff000 to $dff200 to see if anything unusual might be happening, but besides some audio register writes for the music player there was barely anything at all! |
|
01 August 2021, 13:11 | #11 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
Quote:
|
|
01 August 2021, 13:13 | #12 |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
|
01 August 2021, 13:19 | #13 |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
Not A5 - confirmed set to $dff000 every call.
|
01 August 2021, 13:25 | #14 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
|
01 August 2021, 13:31 | #15 |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
Thanks anyway though. The discussion is useful just to make sure I'm not missing obvious things I should look for when diagnosing this sort of problem.
|
01 August 2021, 16:52 | #16 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,039
|
Did you try triggering it at any other VPOS, or maybe even in the second half of line $ff?
If the $dff180 test with 100% selfcontained (no regs, all absolute addressing) bare bones interrupt code comes out clean, it definitely looks like to be what was mentioned right away in post #2. Unless it's some weirdness with winuae and/or wdhload. |
01 August 2021, 17:18 | #17 | |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
Quote:
So I do agree it looks like something is hanging on waiting for a line to be reached in CPU code. Question now is where... Not sure how relevant this is, but there are two copperlists in play here. 1st jumps to 2nd, and the 2nd contains the WAIT followed by COPPER interrupt write. I've already had to look into this due to WHDLoad OS swaps breaking the game (due to OS overwriting cop2lc). In fact it was fixing non-preload mode that made me realise this slowdown existed, because letting WHDLoad do OS swaps was making the game load faster. Last edited by DJ Mike; 01 August 2021 at 17:29. |
|
01 August 2021, 17:23 | #18 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
|
01 August 2021, 18:03 | #19 |
Registered User
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
|
It's OK, stand down. I need to eat humble pie for focussing too much on the problem without being more discerning of settings!
I realised now that I didn't have Cycle Exact Full/DMA turned on, which as soon as I did has undone the speed-up I was getting. Indeed now I've finally had the chance to get on my real Amiga and run the same test, I get none of the speed boost. Curious what the difference is in the emulation there that would give such different speed results if vpos < $1f or >= $1f, without cycle exact. Either way, chock this one up to me being a dunce. Last edited by DJ Mike; 01 August 2021 at 18:36. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Blitter interrupt during VERTB interrupt | phx | Coders. Asm / Hardware | 38 | 01 October 2021 19:54 |
CIA or vertical blank/copper interrupt for playing music in an intro? | pushead | Coders. Asm / Hardware | 25 | 24 April 2021 11:40 |
Blitting from main loop and level 3 interrupt (copper) | nandius_c | Coders. Asm / Hardware | 9 | 07 February 2020 19:15 |
Q: Copper Interrupt | Herpes | Coders. Asm / Hardware | 3 | 25 April 2016 13:31 |
ASM: VERTB int and 16 colored sprites. | Asman | Coders. Tutorials | 5 | 28 April 2010 14:18 |
|
|