Laurent, thank you for adding the patch for testing purpose. I have a very limited amount of DSP software to test with. It seems none of it uses the special addressing with Nn = P*2^k.
About P being positive: The datasheet is quite confusing about this.
"If an offset, Nn, is used in the address calculations, the 16-bit absolute value, |Nn|, must be less than or equal to M for proper modulo addressing. If Nn>M, the result is data dependent and unpredictable, except for the special case where Nn = P x 2^k, a multiple of the block size where P is a positive integer."
It is not clear if Nn in the function Nn = P x 2^k is the absolute value or the signed one. At least when comparing Nn>M the variable Nn seems to stand for the absolute value, while missing the ||.
Douglas' message from october 23rd indicates that the special case also needs to work for (Rn)-Nn addressing (as it does since your second patch). If i understand correctly he tested it on real hardware. With (Rn)-Nn addressing and signed Nn, in the above function P would be negative. So for now i think that the function really is |Nn| = P * 2^k and therefore P = |Nn| / 2^k, which means P is always positive.
I was confused by this for quite some time. But i hope i got it right now.
Note: There is a low chance that the datasheet is to understand in a way that if singed Nn<0 the addressing always works, even if Nn<-M. I think this is unlikely.
Hi Andreas,
I've done some tests with your patch and noticed no regression.
My patch seems to work too.
So, I've uploaded your patch for more tests.
Doug and the others, if you could test your favorite Falcon games
/ demos / utils with the latest patch, it would help.
Doug, is your current devs still work ?
If so, we have 2 versions of the patch (yours that is currently in
the head code and mine that was just before).
It would be easy to return to mine for testing purpose if needed.
I've already tested :
bad mood
bound1
bound2
bound3
eko_system
sololuminescentz
Regards
Laurent
Le 05/11/2015 19:24, Andreas Grabher a écrit :
After some testing i came to the conclusion, that the appended
patch should be correct. I'm not sure if the function currently in
Hatari works in all cases. This is the modified function:
static void
dsp_update_rn_modulo(Uint32 numreg, Sint16 modifier)
{
Uint16
bufsize, bufmask, modulo, abs_modifier;
Uint32
r_reg, lobound, hibound;
r_reg
= dsp_core.registers[DSP_REG_R0+numreg]|0x10000;
modulo
= dsp_core.registers[DSP_REG_M0+numreg]+1;
bufsize
= 1;
while
(bufsize < modulo) {
bufsize
<<= 1;
}
bufmask
= bufsize - 1;
lobound
= r_reg - (r_reg&bufmask);
hibound
= lobound + modulo - 1;
if
(modifier<0) {
abs_modifier
= -modifier;
}
else {
abs_modifier
= modifier;
}
if
(abs_modifier>modulo) {
if
(abs_modifier&bufmask) {
fprintf(stderr,"Dsp:
Modulo addressing result unpredictable\n");
}
else {
r_reg
+= modifier;
}
}
else {
r_reg
+= modifier;
if
(r_reg>hibound) {
r_reg
-= modulo;
}
else if (r_reg<lobound) {
r_reg
+= modulo;
}
}
dsp_core.registers[DSP_REG_R0+numreg]
= r_reg & BITMASK(16);
}
I had a look at
the patch and i'm still not sure, if everything is correct
about it.
I read the data sheet over and over and i made two
new variants. A few things that i don't understand about
the original code:
r_reg beeing Sint16:
if dsp_core.registers[DSP_REG_R0+numreg] is greater
than 0x7FFF, r_reg will be negative, while the unsigned
lobound and hibound will be positive. Won't that cause
problems comparing them?
The calculation that is done, if orig_modifier >
modulo, but Nn = P * 2^k is not true: Where did you get
this from?
Why only doing the modulo operation, if
orig_modifier!=modulo. Shouldn't r_reg be always updated
to modulo bounds?
first variant:
static void dsp_update_rn_modulo(Uint32
numreg, Sint16 modifier)
{
Uint16
bufsize, modulo, lobound, hibound, bufmask,
abs_modifier;
Sint16
r_reg;
modulo
= dsp_core.registers[DSP_REG_M0+numreg]+1;
bufsize
= 1;
while
(bufsize < modulo) {
bufsize
<<= 1;
}
bufmask
= bufsize - 1;
lobound
= dsp_core.registers[DSP_REG_R0+numreg] &
(~bufmask);
hibound
= lobound + modulo - 1;
r_reg
= (Sint16) dsp_core.registers[DSP_REG_R0+numreg];
if
(modifier<0) {
abs_modifier
= -modifier;
}
else {
abs_modifier
= modifier;
}
if
(abs_modifier>modulo) {
if
(abs_modifier&bufmask) {
fprintf(stderr,"Dsp:
Modulo addressing result unpredictable\n");
}
else {
r_reg
+= modifier;
}
}
else {
r_reg
+= modifier;
if
(r_reg>hibound) {
r_reg
-= modulo;
}
else if (r_reg<lobound) {
r_reg
+= modulo;
}
}
dsp_core.registers[DSP_REG_R0+numreg]
= ((Uint32) r_reg) & BITMASK(16);
}
second variant:
static void
dsp_update_rn_modulo(Uint32 numreg, Sint16 modifier)
{
Uint16
bufsize, modulo, bufmask, abs_modifier;
Uint32
r_reg, lobound, hibound;
modulo
= dsp_core.registers[DSP_REG_M0+numreg]+1;
r_reg
= dsp_core.registers[DSP_REG_R0+numreg];
bufsize
= 1;
while
(bufsize < modulo) {
bufsize
<<= 1;
}
bufmask
= bufsize - 1;
lobound
= r_reg & (~bufmask);
hibound
= lobound + modulo - 1;
if
(modifier<0) {
abs_modifier
= -modifier;
}
else {
abs_modifier
= modifier;
}
if
(abs_modifier>modulo) {
if
(abs_modifier&bufmask) {
fprintf(stderr,"Dsp:
Modulo addressing result unpredictable\n");
return;
}
else {
lobound
+= modifier;
hibound
+= modifier;
}
}
r_reg
+= modifier;
if
(r_reg>hibound) {
r_reg
-= modulo;
}
else if (r_reg<lobound) {
r_reg
+= modulo;
}
dsp_core.registers[DSP_REG_R0+numreg]
= r_reg & BITMASK(16);
}
Great news ;)
Regards
Laurent
Le 28/10/2015 17:51, Douglas Little a écrit :
Hi,
Still no problems here - so I think the
patch is working, at least for the cases I
described before :-)
Best,
D.
|