Karoshi MSX Community
12 de Diciembre de 2017, 08:34:02 am *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.

Ingresar con nombre de usuario, contraseña y duración de la sesión
Noticias:
 
   Inicio   Ayuda Buscar Calendario Ingresar Registrarse  
Páginas: [1]
  Imprimir  
Autor Tema: bug in ayFx-ROM.asm from Shappire  (Leído 5593 veces)
0 Usuarios y 1 Visitante están viendo este tema.
ARTRAG
Visitante
« : 15 de Enero de 2009, 10:53:10 am »

I could be wrong, but investigating on the use of ayFX I think I have found a bug.
The ayFX player released here http://z80st-software.blogspot.com/ has a problem in the mixer:

here we have:
Código:
@@SETMASKS: ; --- Set mixer masks ---
ld a,c ; a:=Control byte
and $90 ; Only bits 7 and 4 (noise and tone mask for psg reg 7)
cp $90 ; If no noise and no tone...
ret z ; ...return (don't copy ayFX values in to AYREGS)
; --- Copy ayFX values in to ARYREGS ---
rrc a ; Rotate a to the right (1 TIME)
rrc a ; Rotate a to the right (2 TIMES) (OR mask)
ld d,$DB ; d:=Mask for psg mixer (AND mask)
; --- Calculate next ayFX channel ---
ld hl,ayFX_CHANNEL ; Old ayFX playing channel
dec [hl] ; New ayFX playing channel
jp nz,@@SETCHAN ; If not zero jump to @@SETCHAN
ld [hl],3 ; If zero -> set channel 3
@@SETCHAN: ld b,[hl] ; Channel counter
@@CHK1: ; --- Check if playing channel was 1 ---
djnz @@CHK2 ; Decrement and jump if channel was not 1
@@PLAY_C: ; --- Play ayFX stream on channel C ---
call @@SETMIXER ; Set PSG mixer value (a:=ayFX volume)
                ....

Cntering in this segment, C is the current control byte of the sfx.
The segment analyzes bits 7 and 4 of C
When we call SETMIXER, A is a mask derived from C, where only  bits 5  and 2 have meaning.
In SETMIXER we have this:

Código:
@@SETMIXER: ; --- Set PSG mixer value ---
ld c,a ; c:=OR mask
ld a,[AYREGS+7] ; a:=PSG mixer value
and d ; AND mask
or c ; OR mask
ld [AYREGS+7],a ; PSG mixer value updated
ld a,[ayFX_VOLUME] ; a:=ayFX volume value
ret ; Return

ayFX_END: ; --- End of an ayFX stream ---
xor a ; a:=0
ld [ayFX_PLAYING],a ; There's no ayFX stream to be played!
dec a ; a:=255
ld [ayFX_CURRENT],a ; Lower ayFX stream
ret ; Return

Thus, on exit, C has only bit 5 and 2 that can have meaning.

The problem is now, as the following code pretend to read c as it were register 7 of the AY8910.
The code in fact, tests for bit 2, 1 or 0 in branches for channels C,B and A

Código:
                ....
ld [AYREGS+10],a ; Volume copied in to AYREGS (channel C volume)
bit 2,c ; If tone is off...
ret nz ; ...return
ld hl,[ayFX_TONE] ; ayFX tone value
ld [AYREGS+4],hl ; copied in to AYREGS (channel C tone)
ret ; Return
@@CHK2: ; --- Check if playing channel was 2 ---
rrc d ; Rotate right AND mask
rrc a ; Rotate right OR mask
djnz @@CHK3 ; Decrement and jump if channel was not 2
@@PLAY_B: ; --- Play ayFX stream on channel B ---
call @@SETMIXER ; Set PSG mixer value (a:=ayFX volume)
ld [AYREGS+9],a ; Volume copied in to AYREGS (channel B volume)
bit 1,c ; If tone is off...
ret nz ; ...return
ld hl,[ayFX_TONE] ; ayFX tone value
ld [AYREGS+2],hl ; copied in to AYREGS (channel B tone)
ret ; Return
@@CHK3: ; --- Check if playing channel was 3 ---
rrc d ; Rotate right AND mask
rrc a ; Rotate right OR mask
@@PLAY_A: ; --- Play ayFX stream on channel A ---
call @@SETMIXER ; Set PSG mixer value (a:=ayFX volume)
ld [AYREGS+8],a ; Volume copied in to AYREGS (channel A volume)
bit 0,c ; If tone is off...
ret nz ; ...return
ld hl,[ayFX_TONE] ; ayFX tone value
ld [AYREGS+0],hl ; copied in to AYREGS (channel A tone)
ret


I think that in SETMIXER there is a missing bit that loads in C the value that the rest of the code tests.
Shappire do you agree?

IMHO a patch could be to add a ld c,a here
Código:
@@SETMIXER: ; --- Set PSG mixer value ---
ld c,a ; c:=OR mask
ld a,[AYREGS+7] ; a:=PSG mixer value
and d ; AND mask
or c ; OR mask
ld [AYREGS+7],a ; PSG mixer value updated

[b]                LD    C,A[/b]

ld a,[ayFX_VOLUME] ; a:=ayFX volume value
ret ; Return

ayFX_END: ; --- End of an ayFX stream ---
xor a ; a:=0
ld [ayFX_PLAYING],a ; There's no ayFX stream to be played!
dec a ; a:=255
ld [ayFX_CURRENT],a ; Lower ayFX stream
ret ; Return
« Última modificación: 15 de Enero de 2009, 03:15:23 pm por AR » En línea
SapphiRe_MSX
Visitante
« Respuesta #1 : 15 de Enero de 2009, 03:11:25 pm »

I guess it's not necessary, because the code is using

a -> OR mask (values for tone and noise bits of the channel, extracted from the ayFX control byte)
d -> AND mask (a mask to preserve PSG mixer value except tone and noise bits)

And as the initialization of these values is

Código:
ld a,c
and $90
cp $90   (this instruction does not affect the value of a)
ret z    (neither this one)

rrc a
rrc a
ld d,$DB  (equivalent to %11011011)

We know that in this moment the (maybe) active bits of the OR mask (in register a) are 0 on the AND mask (in register d). Lately, these values are rotated if the playing channel is not 1 (remember in the code 1 -> channel C, 2 -> channel B, 3 -> channel A) as follows:

Código:
rrc d
rrc a

So, when entering on @@SETMIXER subfunction we know that the only bits (maybe) active on register a (the bits of the control byte of the stream) are 0 on the register d (AND mask).

Then, after executing @@SETMIXER

Código:
@@SETMIXER: ; --- Set PSG mixer value ---
ld c,a ; c:=OR mask
ld a,[AYREGS+7] ; a:=PSG mixer value
and d ; AND mask
or c ; OR mask
ld [AYREGS+7],a ; PSG mixer value updated
ld a,[ayFX_VOLUME] ; a:=ayFX volume value
ret ; Return

register c has the OR mask. And the value of the checking bit (2 for channel C, 1 for channel B and 0 for channel A) is the same on registers a and c, so the new instruction

Código:
ld c,a

it's unnecessary. What do you think?
En línea
ARTRAG
Visitante
« Respuesta #2 : 15 de Enero de 2009, 04:35:27 pm »

You are totally right! My patch is not needed
A is rotated 0 times for channel C, once for B and twice for A
Thus for channel C we test bit 2 in C, for channel B we test bit 1, and for channel A we test bit 0!
Sorry for the undue alarm!
Tongue
En línea
ARTRAG
Visitante
« Respuesta #3 : 15 de Enero de 2009, 09:35:00 pm »

In the end there was really the bug, but elsewhere.
Thanks Shappire!!!
 Grin


PS
The ayFX update is/wll be soon on Shappire's blog.
En línea
SapphiRe_MSX
Visitante
« Respuesta #4 : 16 de Enero de 2009, 12:40:09 pm »

In the end there was really the bug, but elsewhere.

Yes, a small one... I've not detected it because QBIQS do not use samples with noise.

Citar
Thanks Shappire!!!

eeemm... Sapphire, Sapphire... not Shappire Grin Grin Grin

Citar
The ayFX update is/wll be soon on Shappire's blog

Is there since yesterday night and maybe there will be a new update soon with some extra features that AR has included on the original code.

Thanks again!
--
Sph.
En línea
ARTRAG
Visitante
« Respuesta #5 : 16 de Enero de 2009, 02:50:34 pm »

Sorry ! SapphiRe SapphiRe SapphiRe
(repeating myself to remember)
SapphiRe SapphiRe SapphiRe SapphiRe
SapphiRe SapphiRe SapphiRe SapphiRe
SapphiRe SapphiRe SapphiRe SapphiRe
 Grin
En línea
ARTRAG
Visitante
« Respuesta #6 : 21 de Enero de 2009, 02:22:47 pm »

SapphiRe has just released new replayers for AYFX!!!
Great work Fernando!!!!
I love them!

« Última modificación: 23 de Enero de 2009, 01:27:11 pm por AR » En línea
SapphiRe_MSX
Visitante
« Respuesta #7 : 22 de Enero de 2009, 03:33:45 pm »

...and there is another update of the replayer, with a more compact code and a more correct treatment of frames with volume zero.

testing now... Tongue Tongue
En línea
Jon_Cortazar
Administrator
Karoshi Forum's God
********
Mensajes: 2777



Ver Perfil WWW Email
« Respuesta #8 : 22 de Enero de 2009, 05:18:35 pm »

kool!  Wink Wink
En línea

Jon Cortázar Abraido (aka El Viejo Archivero)
RELEVO Videogames
[Dioniso: La cafeína está haciendo su trabajo; yo espero hacer el mío.]
[pitpan: Me sigue pareciendo más productivo jugar al SNAIL MAZE que seguir esta discusión.]
Páginas: [1]
  Imprimir  
 
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.21 | SMF © 2013, Simple Machines XHTML 1.0 válido! CSS válido!