|[hatari-devel] Re: DSP addressing bug|
[ Thread Index |
| More lists.tuxfamily.org/hatari-devel Archives
- To: hatari-devel@xxxxxxxxxxxxxxxxxxx, Laurent Sallafranque <laurent.sallafranque@xxxxxxx>
- Subject: [hatari-devel] Re: DSP addressing bug
- From: Douglas Little <doug694@xxxxxxxxxxxxxx>
- Date: Wed, 21 Oct 2015 13:54:31 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=FuRYBCQUQMxrOmonFuSvnBKJxubeJqh2ferOdxXHty4=; b=Yd5ijlxWrKjRbrgCCNF6U1G1aNIhLoht8T4q2yrqLjg7Jc5ChXso5GAI3V+1b9xRn2 boFBWcSINXdq4qzAeH5YwSADBMERx9Ros8WqC1y2mLlyPvXcM8gm/LAFcRF/hnELEMpX B1wpWy16C5BbBJ/GSIPBvQrifSnsaAC6S2Aj4b+qqJd4d+y4CH1Oiz6R+fRoVA/7WXfa x/zvPMXXBKnHazUPi7AW1cLLrhLa9328XosFyZ26y1lMdVD1ywQRWGeG0cqfgFG9ppKe Brvb0jWvO9H7e3SiATsAOSE0jxinVnXKYsq8SiV5VzxOlWNyuijT5a+jPKIbOPb6yDJy ivbw==
This one is almost certainly for Laurent.
So I have now (finally) confirmed that the problem described below is a real bug in Hatari's DSP emulation. It behaves differently from real HW (and from the description in the DSP manual).
When using the DSP modulo/ringbuffer addressing mode (Mn > 0) combined with an offset (+/-Nn) the calculated address (or updated address) is wrong when the Nn increment is a multiple of the ringbuffer 2^k bounding size.
This is an important feature when addressing arrays of ringbuffers
- which is how I discovered it.
i.e. a normal address update (Rn)+ performs ringbuffer addressing where (Rn)+Nn lets you advance to the next ringbuffer without any modulo... or alternatively (Rn+Nn) allows addressing of equal position in a different ringbuffer.
Rn = 0
Nn = 8
Mn = 3-1 ; (addr % 3)
; normal wrapping behaviour...
(Rn)+ ; 0->1
(Rn)+ ; 1->2
(Rn)+ ; 2->0
(Rn)+ ; 0->1
; now advance to new ringbuffer
(Rn)+Nn ; 1->9 (1+8 = 9)
..since Nn=8 is twice the 2^k ringbuffer bound of 4, for a mod of 3)
Here Hatari yields a different answer, having performed modulo on the +Nn update instead of a normal increment by Nn.
I have been using a (rather expensive) temporary workaround which looks a bit like this:
move #-1,m1 ; 2 or 4c : disable ring mode
nop ; 0 or 2c
move (r1)+n1 ; 2c
move #3-1,m1 ; 2 or 4c : restore ring mode
...instead of the intended...
Note that this trick only works when Nn is a multiple of the 2^k ringbuffer bound. In any other case it just wraps.
There is one detail I have not checked properly yet - whether this works when (Nn == ringbuffer 2^k bound), and not just a multiple of 2x or more. I suspect it does, according to the manual, but I only tested with Nn = 2x ring size so far... I'll check this separately but it doesn't much affect the bugreport either way.