[hatari-devel] MP2 question

Tomas Skäre tomas.skare at gmail.com
Sun Jan 23 17:50:54 CET 2011


Hi Laurent,

I'm the correct Tomas (I changed my last name many years ago).

I don't really remember the details about this, since I haven't used the
Atari in about 10 years. I do remember that there were some strange
things with the transferring, though.

After looking at the compensating code for some time now, I will try to
explain the logic behind the code. Basically, the data is shifted two
bits to the left after the transfer.

I assume that you know some about how the registers in the DSP work.

>        movep   X:<<M_RX,A

When reading from the DMA (M_RX), the data ends up in the high
16 bits of A1.

A = 00:ffff00:000000

>        lsr     A
>        lsr     A        Y:DMA_r_state,x0

A is shifted two bits to the right, and the left-over bits from the previous
transfer is fetched into x0, only the highest two bits are set.

A = 00:3fffc0:000000
x0 = c00000

>        or      x0,A     #>$010000,x1

Previous left-over bits are OR:ed together with the new 16-bits and x1 is
set to a special multiple value. This is used to divide by 128 later, and is
essentially just a faster way of shifting down a value.

A = 00:ffffc0:000000

>        lsr     A

I'm really not sure why this is done instead of multiplying by 008000 (i.e.
divide by 256) instead, but I probably had a good reason back then. Might
have something to do with losing bit precision.

A = 00:7fffe0:000000

>        move    A1,x0

A = 00:7fffe0:000000
x0 = 7fffe0

>        mpy     x0,x1,A  #>$ffff,x0

Divide x0 by 128 and store in A. Also set x0 to 00ffff after the multiply.

A = 00:00ffff:c00000

>        and     x0,A     A0,Y:DMA_r_state

Store the shifted two bits into Y:DMA_r_state for the next round.
AND A with 00ffff in case bits from A2 has been shifted down.

>        move    A1,x0

Move the resulting 16-bit value into x0.


So, after the code, x0 contains the correct 16-bit value to use for
the decoder, and Y:DMA_r_state contains the upper two bits that
should be OR:ed together with the next fetched value.


For your example words, I think it will work like this:

>From CPU: $abcd, $1234, $9876

To DSP: $af34, $48d2, $61d8

Note that the top 2 bits from the first 16-bit word are lost here.
For this reason, I think that our DSP player always sent $0000
as first value. That first $0000 would then contain the two lowest
bits from the next value.

The last 16-bit word ($61d8) also assumes that the two extra bits
are zero in this example, but in reality it depends on what comes
after it.

Compare the bit strings:

>From CPU:
abcd12349876  = 101010111100110100010010001101001001100001110110

To DSP:
af3448d261d8  = 101011110011010001001000110100100110000111011000


I hope this helps you. I've tried hatari a bit, and think you are doing
a great job!


Regards,

Tomas


On Fri, Jan 21, 2011 at 13:09, LAURENT SALLAFRANQUE
<laurent.sallafranque at arkea.com> wrote:
> Hi Tomas,
>
> I've spent some time on the DSP MPEG audio layer 2 player a few days ago to let it run under Hatari emulator.
>
> Actually, it doesn't work because transfers between DMA and DSP (crossbar) are using a non documented function.
> (A melt between handshake and non-handshake mode at the same time).
>
> From what I understand, datas are shifted while sent from the DMA play to the DSP receive transfer.
>
> In the DSP code, I can read :
>
>
>        ; Read 16 bits from DMA and
>        ; perform special bit-shifting
>        ; to compensate for read skewness.
>        bset    #4,X:<<M_PCD        ; Start frame sync.
> _wait   jclr    #7,X:<<M_SR,_wait   ; RDF
>        bclr    #4,X:<<M_PCD        ; Stop frame sync.
>        movep   X:<<M_RX,A
>
>        lsr     A
>        lsr     A        Y:DMA_r_state,x0
>        or      x0,A     #>$010000,x1
>        lsr     A
>        move    A1,x0
>        mpy     x0,x1,A  #>$ffff,x0
>        and     x0,A     A0,Y:DMA_r_state
>        move    A1,x0
>
>
> First 4 instructions are waiting a sync data on the SSI port.
> Last 8 instructions "compensate" an undocumented function.
>
>
> I'd like to implement this undocumented transfer into Hatari's emulator to have the player running.
>
> Could anybody tell me (with an example if possible) what exactly happens on the real hardware for this transfer mode ?
>
> For example, if I want to transfer 3 words :
>
> $abcd
> $1234
> $9876
>
> how are they received via the SSI port before the special bit shifting ?
>
> I understand that "A1" register contains the original data which has just been decoded and DMA_r_state contains the "A0" part of the data which is used to decode the next transmitted data.
>
> Thanks in advance.
>
> PS : the one who wrote this is Tomas Berndtsson, <tomas at nocrew.org> from NoBrain/NoCrew
> I've emailed him, but if you know him or if you think you can help me here, this would be great.
>
> Thanks,
> Regards
>
> Laurent
>
> --
> Ce message et  toutes les pieces jointes (ci-apres  le "message") sont
> confidentiels et etablis a l'intention exclusive de ses destinataires.
> Toute  utilisation ou  diffusion  non autorisee  est interdite.   Tout
> message  etant  susceptible  d'alteration,  l'emetteur  decline  toute
> responsabilite au titre de  ce message  s'il a  ete altere, deforme ou
> falsifie.
>                -----------------------------------
> This message and any  attachments (the "message") are confidential and
> intended  solely   for  the   addressees.  Any  unauthorised   use  or
> dissemination is prohibited. As e-mails are susceptible to alteration,
> the issuer shall  not be  liable for  the  message if altered, changed
> or falsified.
>
>



More information about the hatari-devel mailing list