English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 01 August 2021, 10:34   #1
DJ Mike
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.
DJ Mike is offline  
Old 01 August 2021, 11:15   #2
Toni Wilen
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.
Toni Wilen is online now  
Old 01 August 2021, 11:19   #3
ross
Defendit numerus
 
ross's Avatar
 
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
ross is offline  
Old 01 August 2021, 11:21   #4
DJ Mike
Registered User
 
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
Quote:
Originally Posted by ross View Post
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')
PAL picture mode, and 256 lines high by the looks of things.

Checking for line waits in the main code is a good call - I will investigate this.
DJ Mike is offline  
Old 01 August 2021, 11:33   #5
DJ Mike
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.
DJ Mike is offline  
Old 01 August 2021, 12:51   #6
DJ Mike
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.
DJ Mike is offline  
Old 01 August 2021, 12:56   #7
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by DJ Mike View Post
- Skipping everything inside the IRQ code except INTREQ clear. No change - loading still slow.
Can you post this snippet? (full init and exit code)
ross is offline  
Old 01 August 2021, 13:01   #8
DJ Mike
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
My "skip" version was just to run the line of code at $2a00 and RTE. More accurately, I inserted a BRA from $29C8 -> $2A00 and NOPed the movem at $2A06. This didn't improve loading speed. So I don't think anything inside this interrupt code is responsible.

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 ).
DJ Mike is offline  
Old 01 August 2021, 13:06   #9
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by DJ Mike View Post
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 ).
Well, yes and no..
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?
ross is offline  
Old 01 August 2021, 13:09   #10
DJ Mike
Registered User
 
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
Quote:
Originally Posted by ross View Post
Well, yes and no..
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?
INTENA is set to $4018, so no other level 3 bits besides COPPER.
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!
DJ Mike is offline  
Old 01 August 2021, 13:11   #11
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by DJ Mike View Post
INTENA is set to $4018, so no other level 3 bits besides COPPER.
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!
Check A5..
ross is offline  
Old 01 August 2021, 13:13   #12
DJ Mike
Registered User
 
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
Quote:
Originally Posted by ross View Post
Check A5..
Just saw this after my reply. Yes, that's an interesting point I hadn't considered actually. If loading routine is modifying A5 then this routine won't be checking correct address. Will force that to be $dff000 and report back.
DJ Mike is offline  
Old 01 August 2021, 13:19   #13
DJ Mike
Registered User
 
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
Not A5 - confirmed set to $dff000 every call.
DJ Mike is offline  
Old 01 August 2021, 13:25   #14
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by DJ Mike View Post
Not A5 - confirmed set to $dff000 every call.
I have no other ideas
In any case I would fix A5, for whatever reason external code uses A5 this IRQ stops working as it should!
ross is offline  
Old 01 August 2021, 13:31   #15
DJ Mike
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.
DJ Mike is offline  
Old 01 August 2021, 16:52   #16
a/b
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.
a/b is offline  
Old 01 August 2021, 17:18   #17
DJ Mike
Registered User
 
Join Date: Nov 2005
Location: United Kingdom
Age: 40
Posts: 100
Quote:
Originally Posted by a/b View Post
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.
Coincidentally, I'd had this exact same thought - and yes! Changing copperlist to wait until vpos 0 instead of vpos 255 fixes this slowdown. In fact, any vpos of $1e or less will fix this, but as soon as the wait instruction is vpos >= $1f or more, it breaks again.

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.
DJ Mike is offline  
Old 01 August 2021, 17:23   #18
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by DJ Mike View Post
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...
What game is it about?
Maybe more eyes are better than two
ross is offline  
Old 01 August 2021, 18:03   #19
DJ Mike
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.
DJ Mike is offline  
 


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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 14:30.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.09183 seconds with 15 queries